Assertion failure in RenderTreePosition::computeNextSibling
authorantti@apple.com <antti@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 19 Nov 2015 04:14:24 +0000 (04:14 +0000)
committerantti@apple.com <antti@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 19 Nov 2015 04:14:24 +0000 (04:14 +0000)
https://bugs.webkit.org/show_bug.cgi?id=151337
rdar://problem/23250075

Reviewed by Zalan Bujtas.

Source/WebCore:

Test: fast/html/details-mathml-crash.html

* html/ads: Added.
* style/StyleResolveTree.cpp:
(WebCore::Style::resolveChildAtShadowBoundary):

    Factor common code for resolving child here from resolveShadowTree.

(WebCore::Style::resolveShadowTree):

    We don't need StyleResolverParentPusher because shadow tree uses different style resolver anyway.

(WebCore::Style::resolveSlotAssignees):

    This needs to call renderTreePosition.invalidateNextSibling() if there is a renderer already.
    Achieve this by calling the new common function resolveChildAtShadowBoundary.

LayoutTests:

Test case by Pranjal Jumde.

* fast/html/details-mathml-crash-expected.txt: Added.
* fast/html/details-mathml-crash.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@192608 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/fast/html/details-mathml-crash-expected.txt [new file with mode: 0644]
LayoutTests/fast/html/details-mathml-crash.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/style/StyleResolveTree.cpp

index acc5415..ab64f15 100644 (file)
@@ -1,3 +1,16 @@
+2015-11-18  Antti Koivisto  <antti@apple.com>
+
+        Assertion failure in RenderTreePosition::computeNextSibling
+        https://bugs.webkit.org/show_bug.cgi?id=151337
+        rdar://problem/23250075
+
+        Reviewed by Zalan Bujtas.
+
+        Test case by Pranjal Jumde.
+
+        * fast/html/details-mathml-crash-expected.txt: Added.
+        * fast/html/details-mathml-crash.html: Added.
+
 2015-11-18  Jiewen Tan  <jiewen_tan@apple.com>
 
         [WK1] Crash loading Blink layout test fast/dom/Window/property-access-on-cached-window-after-frame-removed.html
diff --git a/LayoutTests/fast/html/details-mathml-crash-expected.txt b/LayoutTests/fast/html/details-mathml-crash-expected.txt
new file mode 100644 (file)
index 0000000..44311f8
--- /dev/null
@@ -0,0 +1,3 @@
+This test passes if it doesn't crash.
+
+
diff --git a/LayoutTests/fast/html/details-mathml-crash.html b/LayoutTests/fast/html/details-mathml-crash.html
new file mode 100644 (file)
index 0000000..bfcd545
--- /dev/null
@@ -0,0 +1,10 @@
+This test passes if it doesn't crash.
+<div><br><summary><mrow></mrow><br>
+<script>
+if (window.testRunner)
+    testRunner.dumpAsText();
+document.execCommand("SelectAll", false, null);
+var style = document.createElement("style");
+style.innerHTML="* { position: absolute; }";
+document.getElementsByTagName("head")[0].appendChild(style);
+</script>
\ No newline at end of file
index 3510d2d..487903f 100644 (file)
@@ -1,3 +1,28 @@
+2015-11-18  Antti Koivisto  <antti@apple.com>
+
+        Assertion failure in RenderTreePosition::computeNextSibling
+        https://bugs.webkit.org/show_bug.cgi?id=151337
+        rdar://problem/23250075
+
+        Reviewed by Zalan Bujtas.
+
+        Test: fast/html/details-mathml-crash.html
+
+        * html/ads: Added.
+        * style/StyleResolveTree.cpp:
+        (WebCore::Style::resolveChildAtShadowBoundary):
+
+            Factor common code for resolving child here from resolveShadowTree.
+
+        (WebCore::Style::resolveShadowTree):
+
+            We don't need StyleResolverParentPusher because shadow tree uses different style resolver anyway.
+
+        (WebCore::Style::resolveSlotAssignees):
+
+            This needs to call renderTreePosition.invalidateNextSibling() if there is a renderer already.
+            Achieve this by calling the new common function resolveChildAtShadowBoundary.
+
 2015-11-18  Jer Noble  <jer.noble@apple.com>
 
         WebGL slow video to texture
index 2f64992..b77d532 100644 (file)
@@ -677,27 +677,29 @@ void resolveTextNode(Text& text, RenderTreePosition& renderTreePosition)
     invalidateWhitespaceOnlyTextSiblingsAfterAttachIfNeeded(text);
 }
 
-static void resolveShadowTree(ShadowRoot& shadowRoot, Element& host, Style::Change change)
+static void resolveChildAtShadowBoundary(Node& child, RenderStyle& inheritedStyle, RenderTreePosition& renderTreePosition, Style::Change change)
 {
-    StyleResolverParentPusher parentPusher(&host);
+    if (auto* renderer = child.renderer())
+        renderTreePosition.invalidateNextSibling(*renderer);
 
+    if (is<Text>(child) && child.needsStyleRecalc()) {
+        resolveTextNode(downcast<Text>(child), renderTreePosition);
+        return;
+    }
+    if (is<Element>(child))
+        resolveTree(downcast<Element>(child), inheritedStyle, renderTreePosition, change);
+}
+
+static void resolveShadowTree(ShadowRoot& shadowRoot, Element& host, Style::Change change)
+{
     ASSERT(shadowRoot.host() == &host);
     ASSERT(host.renderer());
+    auto& inheritedStyle = host.renderer()->style();
     if (shadowRoot.styleChangeType() >= FullStyleChange)
         change = Force;
     RenderTreePosition renderTreePosition(*host.renderer());
-    for (Node* child = shadowRoot.firstChild(); child; child = child->nextSibling()) {
-        if (child->renderer())
-            renderTreePosition.invalidateNextSibling(*child->renderer());
-        if (is<Text>(*child) && child->needsStyleRecalc()) {
-            resolveTextNode(downcast<Text>(*child), renderTreePosition);
-            continue;
-        }
-        if (is<Element>(*child)) {
-            parentPusher.push();
-            resolveTree(downcast<Element>(*child), host.renderer()->style(), renderTreePosition, change);
-        }
-    }
+    for (auto* child = shadowRoot.firstChild(); child; child = child->nextSibling())
+        resolveChildAtShadowBoundary(*child, inheritedStyle, renderTreePosition, change);
 
     shadowRoot.clearNeedsStyleRecalc();
     shadowRoot.clearChildNeedsStyleRecalc();
@@ -804,20 +806,11 @@ static void resolveChildren(Element& current, RenderStyle& inheritedStyle, Chang
 static void resolveSlotAssignees(HTMLSlotElement& slot, RenderStyle& inheritedStyle, RenderTreePosition& renderTreePosition, Change change)
 {
     if (auto* assignedNodes = slot.assignedNodes()) {
-        for (auto* child : *assignedNodes) {
-            if (is<Text>(*child))
-                resolveTextNode(downcast<Text>(*child), renderTreePosition);
-            else if (is<Element>(*child))
-                resolveTree(downcast<Element>(*child), inheritedStyle, renderTreePosition, change);
-        }
-    } else {
-        for (Node* child = slot.firstChild(); child; child = child->nextSibling()) {
-            if (is<Text>(*child))
-                resolveTextNode(downcast<Text>(*child), renderTreePosition);
-            else if (is<Element>(*child))
-                resolveTree(downcast<Element>(*child), inheritedStyle, renderTreePosition, change);
-        }
-    }
+        for (auto* child : *assignedNodes)
+            resolveChildAtShadowBoundary(*child, inheritedStyle, renderTreePosition, change);
+    } else
+        resolveChildren(slot, inheritedStyle, change, renderTreePosition);
+
     slot.clearNeedsStyleRecalc();
     slot.clearChildNeedsStyleRecalc();
 }