[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-9427-gc2be6fc

commit-queue at webkit.org commit-queue at webkit.org
Wed Dec 22 11:21:35 UTC 2010


The following commit has been merged in the debian/experimental branch:
commit 26ad6bb470047b8d60c98613fb4d07f8b235c798
Author: commit-queue at webkit.org <commit-queue at webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Tue Jul 20 16:16:10 2010 +0000

    2010-07-20  Hayato Ito  <hayato at 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 at 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:
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@63747 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index c26f337..f8e50c2 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,15 @@
+2010-07-20  Hayato Ito  <hayato at 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  Stephen White  <senorblanco at chromium.org>
 
         Unreviewed; expectations fix.
diff --git a/LayoutTests/fast/css/css-selector-deeply-nested-expected.txt b/LayoutTests/fast/css/css-selector-deeply-nested-expected.txt
new file mode 100644
index 0000000..1b31717
--- /dev/null
+++ b/LayoutTests/fast/css/css-selector-deeply-nested-expected.txt
@@ -0,0 +1,3 @@
+Test case for http://bugs.webkit.org/show_bug.cgi?id=41129
+
+If browser didn't crash, the test passed.
diff --git a/LayoutTests/fast/css/css-selector-deeply-nested.html b/LayoutTests/fast/css/css-selector-deeply-nested.html
new file mode 100644
index 0000000..8f1612f
--- /dev/null
+++ b/LayoutTests/fast/css/css-selector-deeply-nested.html
@@ -0,0 +1,25 @@
+<html>
+<head></head>
+<body>
+<script>
+function generate_deeply_nested_selector(nest) {
+    var selector = [];
+    for (var i = 0; i < nest; ++i)
+        selector.push('* > ');
+    // We don't add last '*' to the selector so that this CSS Selector is invalid.
+    selector.push(' {background:blue}');
+    var style = document.createElement('style');
+    style.type = 'text/css';
+    style.innerHTML = selector.join('');
+    document.head.appendChild(style);
+}
+
+generate_deeply_nested_selector(400000);
+
+if (window.layoutTestController)
+    layoutTestController.dumpAsText();
+</script>
+<p>Test case for <a href="http://bugs.webkit.org/show_bug.cgi?id=41129">http://bugs.webkit.org/show_bug.cgi?id=41129</a></p>
+<p>If browser didn't crash, the test passed.</p>
+</body>
+</html>
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 2399d33..6bbe17c 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,23 @@
+2010-07-20  Hayato Ito  <hayato at 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:
+
 2010-07-20  Yury Semikhatsky  <yurys at chromium.org>
 
         Reviewed by Pavel Feldman.
diff --git a/WebCore/css/CSSSelector.cpp b/WebCore/css/CSSSelector.cpp
index 47ead5f..b1de4ec 100644
--- a/WebCore/css/CSSSelector.cpp
+++ b/WebCore/css/CSSSelector.cpp
@@ -31,11 +31,83 @@
 #include <wtf/Assertions.h>
 #include <wtf/HashMap.h>
 #include <wtf/StdLibExtras.h>
+#include <wtf/Vector.h>
 
 namespace WebCore {
     
 using namespace HTMLNames;
 
+// A helper class to hold CSSSelectors.
+class CSSSelectorBag : public Noncopyable {
+public:
+    ~CSSSelectorBag()
+    {
+        deleteAllValues(m_stack);
+    }
+
+    bool isEmpty() const
+    {
+        return m_stack.isEmpty();
+    }
+
+    void append(PassOwnPtr<CSSSelector> selector)
+    {
+        if (selector)
+            m_stack.append(selector.leakPtr());
+    }
+
+    PassOwnPtr<CSSSelector> takeAny()
+    {
+        ASSERT(!isEmpty());
+        OwnPtr<CSSSelector> selector = adoptPtr(m_stack.last());
+        m_stack.removeLast();
+        return selector.release();
+    }
+
+private:
+    Vector<CSSSelector*, 16> m_stack;
+};
+
+CSSSelector::~CSSSelector()
+{
+    // We should avoid a recursive destructor call, which causes stack overflow
+    // if CSS Selectors are deeply nested.
+
+    // Early exit if we have already processed the children of this selector.
+    if (m_hasRareData) {
+        if (!m_data.m_rareData)
+            return;
+    } else if (!m_data.m_tagHistory)
+        return;
+
+    CSSSelectorBag selectorsToBeDeleted;
+    if (m_hasRareData) {
+        selectorsToBeDeleted.append(m_data.m_rareData->m_tagHistory.release());
+        selectorsToBeDeleted.append(m_data.m_rareData->m_simpleSelector.release());
+        delete m_data.m_rareData;
+    } else
+        selectorsToBeDeleted.append(adoptPtr(m_data.m_tagHistory));
+
+    // Traverse the tree of CSSSelector and delete each CSSSelector iteratively.
+    while (!selectorsToBeDeleted.isEmpty()) {
+        OwnPtr<CSSSelector> selector(selectorsToBeDeleted.takeAny());
+        ASSERT(selector);
+        if (selector->m_hasRareData) {
+            ASSERT(selector->m_data.m_rareData);
+            selectorsToBeDeleted.append(selector->m_data.m_rareData->m_tagHistory.release());
+            selectorsToBeDeleted.append(selector->m_data.m_rareData->m_simpleSelector.release());
+            delete selector->m_data.m_rareData;
+            // Clear the pointer so that a destructor of the selector, which is
+            // about to be called, can know the children are already processed.
+            selector->m_data.m_rareData = 0;
+        } else {
+            selectorsToBeDeleted.append(adoptPtr(selector->m_data.m_tagHistory));
+            // Clear the pointer for the same reason.
+            selector->m_data.m_tagHistory = 0;
+        }
+    }
+}
+
 unsigned int CSSSelector::specificity()
 {
     if (m_isForPage)
@@ -63,6 +135,7 @@ unsigned int CSSSelector::specificity()
             break;
     }
 
+    // FIXME: Avoid recursive calls to prevent possible stack overflow.
     if (CSSSelector* tagHistory = this->tagHistory())
         s += tagHistory->specificity();
 
@@ -906,5 +979,5 @@ bool CSSSelector::RareData::matchNth(int count)
         return (m_b - count) % (-m_a) == 0;
     }
 }
-    
+
 } // namespace WebCore
diff --git a/WebCore/css/CSSSelector.h b/WebCore/css/CSSSelector.h
index fc0dd7b..518ff2c 100644
--- a/WebCore/css/CSSSelector.h
+++ b/WebCore/css/CSSSelector.h
@@ -22,8 +22,8 @@
 #ifndef CSSSelector_h
 #define CSSSelector_h
 
-#include "RenderStyleConstants.h"
 #include "QualifiedName.h"
+#include "RenderStyleConstants.h"
 #include <wtf/Noncopyable.h>
 #include <wtf/OwnPtr.h>
 #include <wtf/PassOwnPtr.h>
@@ -57,13 +57,7 @@ namespace WebCore {
         {
         }
 
-        ~CSSSelector()
-        {
-            if (m_hasRareData)
-                delete m_data.m_rareData;
-            else
-                delete m_data.m_tagHistory;
-        }
+        ~CSSSelector();
 
         /**
          * Re-create selector text from selector's data

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list