Title: [133658] branches/safari-536.28-branch

Diff

Modified: branches/safari-536.28-branch/LayoutTests/ChangeLog (133657 => 133658)


--- branches/safari-536.28-branch/LayoutTests/ChangeLog	2012-11-06 20:25:52 UTC (rev 133657)
+++ branches/safari-536.28-branch/LayoutTests/ChangeLog	2012-11-06 20:43:39 UTC (rev 133658)
@@ -1,5 +1,22 @@
 2012-11-06  Lucas Forschler  <[email protected]>
 
+        Merge r125988
+
+    2012-08-19  MORITA Hajime  <[email protected]>
+
+            DOM mutation against including <link> shouldn't trigger pending HTML parser.
+            https://bugs.webkit.org/show_bug.cgi?id=93641
+
+            Reviewed by Ryosuke Niwa.
+
+            Note that the test content need to be such cryptic because HTML parser is involving the
+            captured bug and adding explanations can affect the behavior then mask the bug.
+
+            * http/tests/loading/remove-child-triggers-parser-expected.txt: Added.
+            * http/tests/loading/remove-child-triggers-parser.html: Added.
+
+2012-11-06  Lucas Forschler  <[email protected]>
+
         Merge r126144
 
     2012-08-21  Chris Evans  <[email protected]>
@@ -11075,3 +11092,4 @@
 .
 .
 .
+.

Copied: branches/safari-536.28-branch/LayoutTests/http/tests/loading/remove-child-triggers-parser-expected.txt (from rev 125988, trunk/LayoutTests/http/tests/loading/remove-child-triggers-parser-expected.txt) (0 => 133658)


--- branches/safari-536.28-branch/LayoutTests/http/tests/loading/remove-child-triggers-parser-expected.txt	                        (rev 0)
+++ branches/safari-536.28-branch/LayoutTests/http/tests/loading/remove-child-triggers-parser-expected.txt	2012-11-06 20:43:39 UTC (rev 133658)
@@ -0,0 +1,6 @@
+main frame - didStartProvisionalLoadForFrame
+main frame - didCommitLoadForFrame
+main frame - didFinishDocumentLoadForFrame
+main frame - didHandleOnloadEventsForFrame
+main frame - didFinishLoadForFrame
+

Copied: branches/safari-536.28-branch/LayoutTests/http/tests/loading/remove-child-triggers-parser.html (from rev 125988, trunk/LayoutTests/http/tests/loading/remove-child-triggers-parser.html) (0 => 133658)


--- branches/safari-536.28-branch/LayoutTests/http/tests/loading/remove-child-triggers-parser.html	                        (rev 0)
+++ branches/safari-536.28-branch/LayoutTests/http/tests/loading/remove-child-triggers-parser.html	2012-11-06 20:43:39 UTC (rev 133658)
@@ -0,0 +1,18 @@
+<script></script>
+<!-- This test covers Bug 93641 -->
+<script>
+if (window.testRunner)
+    testRunner.dumpAsText();
+setTimeout(function() { var child = document.documentElement; child.parentNode.removeChild(child); }, 36);
+</script>
+<script></script>
+<span></span>
+<div></div>
+<span></span>
+<nobr>
+<span></span>
+<div>
+  <link rel="stylesheet" href=""
+  <script>;</script>
+  <nobr>
+</div>

Modified: branches/safari-536.28-branch/Source/WebCore/ChangeLog (133657 => 133658)


--- branches/safari-536.28-branch/Source/WebCore/ChangeLog	2012-11-06 20:25:52 UTC (rev 133657)
+++ branches/safari-536.28-branch/Source/WebCore/ChangeLog	2012-11-06 20:43:39 UTC (rev 133658)
@@ -1,5 +1,42 @@
 2012-11-06  Lucas Forschler  <[email protected]>
 
+        Merge r125988
+
+    2012-08-19  MORITA Hajime  <[email protected]>
+
+            DOM mutation against including <link> shouldn't trigger pending HTML parser.
+            https://bugs.webkit.org/show_bug.cgi?id=93641
+
+            Reviewed by Ryosuke Niwa.
+
+            HTMLLinkElement::removedFrom() invoked Document::removePendingSheet(), which can trigger
+            HTMLParser that can mutate DOM tree. DOM mutation reentrancy on like this is problematic and
+            should be prohibited.
+
+            This change add an variation of Document::removePendingSheet() which postpones the notification
+            which triggers DOM mutation, and flush such pending notifications at the end of ongoing mutation.
+
+            Test: http/tests/loading/remove-child-triggers-parser.html
+
+            * dom/ContainerNodeAlgorithms.h:
+            (WebCore::ChildNodeRemovalNotifier::notify): Flushed pending notifications at the end.
+            * dom/Document.cpp:
+            (WebCore::Document::Document):
+            (WebCore::Document::removePendingSheet): Added RemovePendingSheetNotificationType parameter.
+            (WebCore):
+            (WebCore::Document::didRemoveAllPendingStylesheet): Extracted from removePendingSheet()
+            * dom/Document.h:
+            (Document):
+            (WebCore::Document::setNeedsNotifyRemoveAllPendingStylesheet): A flag setter.
+            (WebCore::Document::notifyRemovePendingSheetIfNeeded):
+            (WebCore):
+            * html/HTMLLinkElement.cpp:
+            (WebCore::HTMLLinkElement::removedFrom): Switched to use "notification later" version of removePendingSheet()
+            (WebCore::HTMLLinkElement::removePendingSheet): Added RemovePendingSheetNotificationType parameter.
+            * html/HTMLLinkElement.h:
+
+2012-11-06  Lucas Forschler  <[email protected]>
+
         Merge r125631
 
     2012-08-14  Chris Evans  <[email protected]>
@@ -206693,3 +206730,4 @@
 .
 .
 .
+.

Modified: branches/safari-536.28-branch/Source/WebCore/dom/ContainerNodeAlgorithms.h (133657 => 133658)


--- branches/safari-536.28-branch/Source/WebCore/dom/ContainerNodeAlgorithms.h	2012-11-06 20:25:52 UTC (rev 133657)
+++ branches/safari-536.28-branch/Source/WebCore/dom/ContainerNodeAlgorithms.h	2012-11-06 20:43:39 UTC (rev 133658)
@@ -259,9 +259,10 @@
 
 inline void ChildNodeRemovalNotifier::notify(Node* node)
 {
-    if (node->inDocument())
+    if (node->inDocument()) {
         notifyNodeRemovedFromDocument(node);
-    else if (node->isContainerNode())
+        node->document()->notifyRemovePendingSheetIfNeeded();
+    } else if (node->isContainerNode())
         notifyNodeRemovedFromTree(toContainerNode(node));
 }
 

Modified: branches/safari-536.28-branch/Source/WebCore/dom/Document.cpp (133657 => 133658)


--- branches/safari-536.28-branch/Source/WebCore/dom/Document.cpp	2012-11-06 20:25:52 UTC (rev 133657)
+++ branches/safari-536.28-branch/Source/WebCore/dom/Document.cpp	2012-11-06 20:43:39 UTC (rev 133658)
@@ -535,6 +535,7 @@
     m_hasDirtyStyleResolver = false;
     m_pendingStylesheets = 0;
     m_ignorePendingStylesheets = false;
+    m_needsNotifyRemoveAllPendingStylesheet = false;
     m_hasNodesWithPlaceholderStyle = false;
     m_pendingSheetLayout = NoLayoutWithPendingSheets;
 
@@ -3204,7 +3205,7 @@
 }
 
 // This method is called whenever a top-level stylesheet has finished loading.
-void Document::removePendingSheet()
+void Document::removePendingSheet(RemovePendingSheetNotificationType notification)
 {
     // Make sure we knew this sheet was pending, and that our count isn't out of sync.
     ASSERT(m_pendingStylesheets > 0);
@@ -3219,6 +3220,18 @@
     if (m_pendingStylesheets)
         return;
 
+    if (notification == RemovePendingSheetNotifyLater) {
+        setNeedsNotifyRemoveAllPendingStylesheet();
+        return;
+    }
+    
+    didRemoveAllPendingStylesheet();
+}
+
+void Document::didRemoveAllPendingStylesheet()
+{
+    m_needsNotifyRemoveAllPendingStylesheet = false;
+
     styleResolverChanged(RecalcStyleIfNeeded);
 
     if (ScriptableDocumentParser* parser = scriptableDocumentParser())
@@ -3228,6 +3241,7 @@
         view()->scrollToFragment(m_url);
 }
 
+
 void Document::evaluateMediaQueryList()
 {
     if (m_mediaQueryMatcher)

Modified: branches/safari-536.28-branch/Source/WebCore/dom/Document.h (133657 => 133658)


--- branches/safari-536.28-branch/Source/WebCore/dom/Document.h	2012-11-06 20:25:52 UTC (rev 133657)
+++ branches/safari-536.28-branch/Source/WebCore/dom/Document.h	2012-11-06 20:43:39 UTC (rev 133658)
@@ -477,8 +477,14 @@
     /**
      * Updates the pending sheet count and then calls updateActiveStylesheets.
      */
-    void removePendingSheet();
+    enum RemovePendingSheetNotificationType {
+        RemovePendingSheetNotifyImmediately,
+        RemovePendingSheetNotifyLater
+    };
 
+    void removePendingSheet(RemovePendingSheetNotificationType = RemovePendingSheetNotifyImmediately);
+    void notifyRemovePendingSheetIfNeeded();
+
     /**
      * This method returns true if all top-level stylesheets have loaded (including
      * any @imports that they may be loading).
@@ -1208,6 +1214,8 @@
     void collectActiveStylesheets(Vector<RefPtr<StyleSheet> >&);
     bool testAddedStylesheetRequiresStyleRecalc(StyleSheetInternal*);
     void analyzeStylesheetChange(StyleResolverUpdateFlag, const Vector<RefPtr<StyleSheet> >& newStylesheets, bool& requiresStyleResolverReset, bool& requiresFullStyleRecalc);
+    void didRemoveAllPendingStylesheet();
+    void setNeedsNotifyRemoveAllPendingStylesheet() { m_needsNotifyRemoveAllPendingStylesheet = true; }
 
     void deleteCustomFonts();
 
@@ -1276,7 +1284,8 @@
 
     // But sometimes you need to ignore pending stylesheet count to
     // force an immediate layout when requested by JS.
-    bool m_ignorePendingStylesheets;
+    bool m_ignorePendingStylesheets : 1;
+    bool m_needsNotifyRemoveAllPendingStylesheet : 1;
 
     // If we do ignore the pending stylesheet count, then we need to add a boolean
     // to track that this happened so that we can do a full repaint when the stylesheets
@@ -1511,6 +1520,12 @@
 #endif
 };
 
+inline void Document::notifyRemovePendingSheetIfNeeded()
+{
+    if (m_needsNotifyRemoveAllPendingStylesheet)
+        didRemoveAllPendingStylesheet();
+}
+
 // Put these methods here, because they require the Document definition, but we really want to inline them.
 
 inline bool Node::isDocumentNode() const

Modified: branches/safari-536.28-branch/Source/WebCore/html/HTMLLinkElement.cpp (133657 => 133658)


--- branches/safari-536.28-branch/Source/WebCore/html/HTMLLinkElement.cpp	2012-11-06 20:25:52 UTC (rev 133657)
+++ branches/safari-536.28-branch/Source/WebCore/html/HTMLLinkElement.cpp	2012-11-06 20:43:39 UTC (rev 133658)
@@ -275,7 +275,7 @@
         clearSheet();
 
     if (styleSheetIsLoading())
-        removePendingSheet();
+        removePendingSheet(RemovePendingSheetNotifyLater);
 
     if (document()->renderer())
         document()->styleResolverChanged(DeferRecalcStyle);
@@ -445,7 +445,7 @@
     document()->addPendingSheet();
 }
 
-void HTMLLinkElement::removePendingSheet()
+void HTMLLinkElement::removePendingSheet(RemovePendingSheetNotificationType notification)
 {
     PendingSheetType type = m_pendingSheetType;
     m_pendingSheetType = None;
@@ -457,7 +457,11 @@
         document()->styleResolverChanged(RecalcStyleImmediately);
         return;
     }
-    document()->removePendingSheet();
+
+    document()->removePendingSheet(
+        notification == RemovePendingSheetNotifyImmediately
+        ? Document::RemovePendingSheetNotifyImmediately
+        : Document::RemovePendingSheetNotifyLater);
 }
 
 DOMSettableTokenList* HTMLLinkElement::sizes() const

Modified: branches/safari-536.28-branch/Source/WebCore/html/HTMLLinkElement.h (133657 => 133658)


--- branches/safari-536.28-branch/Source/WebCore/html/HTMLLinkElement.h	2012-11-06 20:25:52 UTC (rev 133657)
+++ branches/safari-536.28-branch/Source/WebCore/html/HTMLLinkElement.h	2012-11-06 20:43:39 UTC (rev 133658)
@@ -100,8 +100,14 @@
     
     enum PendingSheetType { None, NonBlocking, Blocking };
     void addPendingSheet(PendingSheetType);
-    void removePendingSheet();
 
+    enum RemovePendingSheetNotificationType {
+        RemovePendingSheetNotifyImmediately,
+        RemovePendingSheetNotifyLater
+    };
+
+    void removePendingSheet(RemovePendingSheetNotificationType = RemovePendingSheetNotifyImmediately);
+
 #if ENABLE(MICRODATA)
     virtual String itemValueText() const OVERRIDE;
     virtual void setItemValueText(const String&, ExceptionCode&) OVERRIDE;
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to