Changeset 63747 in webkit


Ignore:
Timestamp:
Jul 20, 2010 9:16:10 AM (14 years ago)
Author:
commit-queue@webkit.org
Message:

2010-07-20 Hayato Ito <hayato@chromium.org>

Reviewed by Darin Adler.

Fixed a crash when deeply nested CSS selector is used.
https://bugs.webkit.org/show_bug.cgi?id=41129

This patch deletes CSSSelectors iteratively so that it doesn't cause stack overflow.

  • fast/css/css-selector-deeply-nested-expected.txt: Added.
  • fast/css/css-selector-deeply-nested.html: Added.

2010-07-20 Hayato Ito <hayato@chromium.org>

Reviewed by Darin Adler.

Fixed a crash when deeply nested CSS selector is used.
https://bugs.webkit.org/show_bug.cgi?id=41129

This patch deletes CSSSelectors iteratively so that it doesn't cause stack overflow.

Test: fast/css/css-selector-deeply-nested.html

  • css/CSSSelector.cpp: (WebCore::CSSSelectorBag::~CSSSelectorBag): (WebCore::CSSSelectorBag::isEmpty): (WebCore::CSSSelectorBag::append): (WebCore::CSSSelectorBag::takeAny): (WebCore::CSSSelector::~CSSSelector): (WebCore::CSSSelector::specificity):
  • css/CSSSelector.h:
Location:
trunk
Files:
2 added
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r63744 r63747  
     12010-07-20  Hayato Ito  <hayato@chromium.org>
     2
     3        Reviewed by Darin Adler.
     4
     5        Fixed a crash when deeply nested CSS selector is used.
     6        https://bugs.webkit.org/show_bug.cgi?id=41129
     7
     8        This patch deletes CSSSelectors iteratively so that it doesn't cause stack overflow.
     9
     10        * fast/css/css-selector-deeply-nested-expected.txt: Added.
     11        * fast/css/css-selector-deeply-nested.html: Added.
     12
    1132010-07-20  Stephen White  <senorblanco@chromium.org>
    214
  • trunk/WebCore/ChangeLog

    r63746 r63747  
     12010-07-20  Hayato Ito  <hayato@chromium.org>
     2
     3        Reviewed by Darin Adler.
     4
     5        Fixed a crash when deeply nested CSS selector is used.
     6        https://bugs.webkit.org/show_bug.cgi?id=41129
     7
     8        This patch deletes CSSSelectors iteratively so that it doesn't cause stack overflow.
     9
     10        Test: fast/css/css-selector-deeply-nested.html
     11
     12        * css/CSSSelector.cpp:
     13        (WebCore::CSSSelectorBag::~CSSSelectorBag):
     14        (WebCore::CSSSelectorBag::isEmpty):
     15        (WebCore::CSSSelectorBag::append):
     16        (WebCore::CSSSelectorBag::takeAny):
     17        (WebCore::CSSSelector::~CSSSelector):
     18        (WebCore::CSSSelector::specificity):
     19        * css/CSSSelector.h:
     20
    1212010-07-20  Yury Semikhatsky  <yurys@chromium.org>
    222
  • trunk/WebCore/css/CSSSelector.cpp

    r62821 r63747  
    3232#include <wtf/HashMap.h>
    3333#include <wtf/StdLibExtras.h>
     34#include <wtf/Vector.h>
    3435
    3536namespace WebCore {
    3637   
    3738using namespace HTMLNames;
     39
     40// A helper class to hold CSSSelectors.
     41class CSSSelectorBag : public Noncopyable {
     42public:
     43    ~CSSSelectorBag()
     44    {
     45        deleteAllValues(m_stack);
     46    }
     47
     48    bool isEmpty() const
     49    {
     50        return m_stack.isEmpty();
     51    }
     52
     53    void append(PassOwnPtr<CSSSelector> selector)
     54    {
     55        if (selector)
     56            m_stack.append(selector.leakPtr());
     57    }
     58
     59    PassOwnPtr<CSSSelector> takeAny()
     60    {
     61        ASSERT(!isEmpty());
     62        OwnPtr<CSSSelector> selector = adoptPtr(m_stack.last());
     63        m_stack.removeLast();
     64        return selector.release();
     65    }
     66
     67private:
     68    Vector<CSSSelector*, 16> m_stack;
     69};
     70
     71CSSSelector::~CSSSelector()
     72{
     73    // We should avoid a recursive destructor call, which causes stack overflow
     74    // if CSS Selectors are deeply nested.
     75
     76    // Early exit if we have already processed the children of this selector.
     77    if (m_hasRareData) {
     78        if (!m_data.m_rareData)
     79            return;
     80    } else if (!m_data.m_tagHistory)
     81        return;
     82
     83    CSSSelectorBag selectorsToBeDeleted;
     84    if (m_hasRareData) {
     85        selectorsToBeDeleted.append(m_data.m_rareData->m_tagHistory.release());
     86        selectorsToBeDeleted.append(m_data.m_rareData->m_simpleSelector.release());
     87        delete m_data.m_rareData;
     88    } else
     89        selectorsToBeDeleted.append(adoptPtr(m_data.m_tagHistory));
     90
     91    // Traverse the tree of CSSSelector and delete each CSSSelector iteratively.
     92    while (!selectorsToBeDeleted.isEmpty()) {
     93        OwnPtr<CSSSelector> selector(selectorsToBeDeleted.takeAny());
     94        ASSERT(selector);
     95        if (selector->m_hasRareData) {
     96            ASSERT(selector->m_data.m_rareData);
     97            selectorsToBeDeleted.append(selector->m_data.m_rareData->m_tagHistory.release());
     98            selectorsToBeDeleted.append(selector->m_data.m_rareData->m_simpleSelector.release());
     99            delete selector->m_data.m_rareData;
     100            // Clear the pointer so that a destructor of the selector, which is
     101            // about to be called, can know the children are already processed.
     102            selector->m_data.m_rareData = 0;
     103        } else {
     104            selectorsToBeDeleted.append(adoptPtr(selector->m_data.m_tagHistory));
     105            // Clear the pointer for the same reason.
     106            selector->m_data.m_tagHistory = 0;
     107        }
     108    }
     109}
    38110
    39111unsigned int CSSSelector::specificity()
     
    64136    }
    65137
     138    // FIXME: Avoid recursive calls to prevent possible stack overflow.
    66139    if (CSSSelector* tagHistory = this->tagHistory())
    67140        s += tagHistory->specificity();
     
    907980    }
    908981}
    909    
     982
    910983} // namespace WebCore
  • trunk/WebCore/css/CSSSelector.h

    r62821 r63747  
    2323#define CSSSelector_h
    2424
     25#include "QualifiedName.h"
    2526#include "RenderStyleConstants.h"
    26 #include "QualifiedName.h"
    2727#include <wtf/Noncopyable.h>
    2828#include <wtf/OwnPtr.h>
     
    5858        }
    5959
    60         ~CSSSelector()
    61         {
    62             if (m_hasRareData)
    63                 delete m_data.m_rareData;
    64             else
    65                 delete m_data.m_tagHistory;
    66         }
     60        ~CSSSelector();
    6761
    6862        /**
Note: See TracChangeset for help on using the changeset viewer.