Title: [225014] trunk
Revision
225014
Author
[email protected]
Date
2017-11-18 03:46:06 -0800 (Sat, 18 Nov 2017)

Log Message

Source/WebCore:
REGRESSION (r220646): REGRESSION (r220646): RenderTreePosition::computeNextSibling hits assertion with certain first-letter mutations
https://bugs.webkit.org/show_bug.cgi?id=179855
<rdar://problem/35464071>

Reviewed by Zalan Bujtas.

Test: fast/css-generated-content/first-letter-update-crash.html

* style/RenderTreeUpdaterFirstLetter.cpp:
(WebCore::styleForFirstLetter):
(WebCore::updateFirstLetterStyle):
(WebCore::createFirstLetterRenderer):

    Tighten these to take RenderBlock.

(WebCore::supportsFirstLetter):

    Test exact conditions where first letter renderer is allowed for fast rejection.

(WebCore::RenderTreeUpdater::FirstLetter::update):

    If update was called on a block that doesn't support first letter, getFirstLetter could in
    some cases return an ancestor of the block and we would end up mutating a first letter renderer
    that wasn't current block's descendant. This violates assumptions of the RenderTreeUpdater
    and could cause cached render tree position to become invalid.

    Fix by ensuring we are always updating first letter for the current block only.

LayoutTests:
REGRESSION (r220646): ASSERTION FAILED: skipAssert || nextSiblingRenderer(node) == m_nextSibling
https://bugs.webkit.org/show_bug.cgi?id=179855
<rdar://problem/35464071>

Reviewed by Zalan Bujtas.

* fast/css-generated-content/first-letter-update-crash-expected.txt: Added.
* fast/css-generated-content/first-letter-update-crash.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (225013 => 225014)


--- trunk/LayoutTests/ChangeLog	2017-11-18 06:32:23 UTC (rev 225013)
+++ trunk/LayoutTests/ChangeLog	2017-11-18 11:46:06 UTC (rev 225014)
@@ -1,3 +1,14 @@
+2017-11-18  Antti Koivisto  <[email protected]>
+
+        REGRESSION (r220646): ASSERTION FAILED: skipAssert || nextSiblingRenderer(node) == m_nextSibling
+        https://bugs.webkit.org/show_bug.cgi?id=179855
+        <rdar://problem/35464071>
+
+        Reviewed by Zalan Bujtas.
+
+        * fast/css-generated-content/first-letter-update-crash-expected.txt: Added.
+        * fast/css-generated-content/first-letter-update-crash.html: Added.
+
 2017-11-17  Megan Gardner  <[email protected]>
 
         Rebaseline and/or turn on more iOS selection tests that either already pass, or need minimal visual tweaking

Added: trunk/LayoutTests/fast/css-generated-content/first-letter-update-crash-expected.txt (0 => 225014)


--- trunk/LayoutTests/fast/css-generated-content/first-letter-update-crash-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/css-generated-content/first-letter-update-crash-expected.txt	2017-11-18 11:46:06 UTC (rev 225014)
@@ -0,0 +1 @@
+This test passes if it doesn't assert or crash.

Added: trunk/LayoutTests/fast/css-generated-content/first-letter-update-crash.html (0 => 225014)


--- trunk/LayoutTests/fast/css-generated-content/first-letter-update-crash.html	                        (rev 0)
+++ trunk/LayoutTests/fast/css-generated-content/first-letter-update-crash.html	2017-11-18 11:46:06 UTC (rev 225014)
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html>
+<body>
+<input value='foo'>
+This test passes if it doesn't assert or crash.
+</body>
+<script>
+if (window.testRunner)
+    testRunner.dumpAsText();
+
+const head = document.getElementsByTagName("head")[0];
+let style = document.createElement("style");
+style.innerHTML = "::first-letter { color:blue; }";
+head.appendChild(style);
+
+document.body.offsetLeft;
+
+style = document.createElement("style");
+style.innerHTML = "* { position: absolute; }";
+head.appendChild(style);
+</script>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (225013 => 225014)


--- trunk/Source/WebCore/ChangeLog	2017-11-18 06:32:23 UTC (rev 225013)
+++ trunk/Source/WebCore/ChangeLog	2017-11-18 11:46:06 UTC (rev 225014)
@@ -1,3 +1,33 @@
+2017-11-18  Antti Koivisto  <[email protected]>
+
+        REGRESSION (r220646): REGRESSION (r220646): RenderTreePosition::computeNextSibling hits assertion with certain first-letter mutations
+        https://bugs.webkit.org/show_bug.cgi?id=179855
+        <rdar://problem/35464071>
+
+        Reviewed by Zalan Bujtas.
+
+        Test: fast/css-generated-content/first-letter-update-crash.html
+
+        * style/RenderTreeUpdaterFirstLetter.cpp:
+        (WebCore::styleForFirstLetter):
+        (WebCore::updateFirstLetterStyle):
+        (WebCore::createFirstLetterRenderer):
+
+            Tighten these to take RenderBlock.
+
+        (WebCore::supportsFirstLetter):
+
+            Test exact conditions where first letter renderer is allowed for fast rejection.
+
+        (WebCore::RenderTreeUpdater::FirstLetter::update):
+
+            If update was called on a block that doesn't support first letter, getFirstLetter could in
+            some cases return an ancestor of the block and we would end up mutating a first letter renderer
+            that wasn't current block's descendant. This violates assumptions of the RenderTreeUpdater
+            and could cause cached render tree position to become invalid.
+
+            Fix by ensuring we are always updating first letter for the current block only.
+
 2017-11-17  Chris Dumez  <[email protected]>
 
         [Service Workers] Implement "Notify Controller Change" algorithm

Modified: trunk/Source/WebCore/style/RenderTreeUpdaterFirstLetter.cpp (225013 => 225014)


--- trunk/Source/WebCore/style/RenderTreeUpdaterFirstLetter.cpp	2017-11-18 06:32:23 UTC (rev 225013)
+++ trunk/Source/WebCore/style/RenderTreeUpdaterFirstLetter.cpp	2017-11-18 11:46:06 UTC (rev 225014)
@@ -26,6 +26,7 @@
 
 #include "FontCascade.h"
 #include "RenderBlock.h"
+#include "RenderButton.h"
 #include "RenderInline.h"
 #include "RenderRubyRun.h"
 #include "RenderSVGText.h"
@@ -35,7 +36,7 @@
 
 namespace WebCore {
 
-static RenderStyle styleForFirstLetter(const RenderElement& firstLetterBlock, const RenderObject& firstLetterContainer)
+static RenderStyle styleForFirstLetter(const RenderBlock& firstLetterBlock, const RenderObject& firstLetterContainer)
 {
     auto* containerFirstLetterStyle = firstLetterBlock.getCachedPseudoStyle(FIRST_LETTER, &firstLetterContainer.firstLineStyle());
     // FIXME: There appears to be some path where we have a first letter renderer without first letter style.
@@ -99,7 +100,7 @@
     return isSpaceOrNewline(c) || c == noBreakSpace || isPunctuationForFirstLetter(c);
 }
 
-static void updateFirstLetterStyle(RenderElement& firstLetterBlock, RenderObject& currentChild)
+static void updateFirstLetterStyle(RenderBlock& firstLetterBlock, RenderObject& currentChild)
 {
     RenderElement* firstLetter = currentChild.parent();
     ASSERT(firstLetter->isFirstLetter());
@@ -139,7 +140,7 @@
         firstLetter->setStyle(WTFMove(pseudoStyle));
 }
 
-static void createFirstLetterRenderer(RenderElement& firstLetterBlock, RenderText& currentTextChild)
+static void createFirstLetterRenderer(RenderBlock& firstLetterBlock, RenderText& currentTextChild)
 {
     RenderElement* firstLetterContainer = currentTextChild.parent();
     auto pseudoStyle = styleForFirstLetter(firstLetterBlock, *firstLetterContainer);
@@ -209,42 +210,47 @@
 
 static bool supportsFirstLetter(RenderBlock& block)
 {
-    if (is<RenderTable>(block))
+    if (is<RenderButton>(block))
+        return true;
+    if (!is<RenderBlockFlow>(block))
         return false;
     if (is<RenderSVGText>(block))
         return false;
     if (is<RenderRubyRun>(block))
         return false;
-    return true;
+    return block.canHaveGeneratedChildren();
 }
 
 void RenderTreeUpdater::FirstLetter::update(RenderBlock& block)
 {
-    ASSERT_WITH_SECURITY_IMPLICATION(!block.view().frameView().layoutContext().layoutState());
-
+    if (!block.style().hasPseudoStyle(FIRST_LETTER))
+        return;
     if (!supportsFirstLetter(block))
         return;
 
-    RenderObject* firstLetterObj;
+    // FIXME: This should be refactored, firstLetterContainer is not needed.
+    RenderObject* firstLetterRenderer;
     RenderElement* firstLetterContainer;
-    // FIXME: The first letter might be composed of a variety of code units, and therefore might
-    // be contained within multiple RenderElements.
-    block.getFirstLetter(firstLetterObj, firstLetterContainer);
+    block.getFirstLetter(firstLetterRenderer, firstLetterContainer);
 
-    if (!firstLetterObj || !firstLetterContainer)
+    if (!firstLetterRenderer)
         return;
 
+    // Other containers are handled when updating their renderers.
+    if (&block != firstLetterContainer)
+        return;
+
     // If the child already has style, then it has already been created, so we just want
     // to update it.
-    if (firstLetterObj->parent()->style().styleType() == FIRST_LETTER) {
-        updateFirstLetterStyle(*firstLetterContainer, *firstLetterObj);
+    if (firstLetterRenderer->parent()->style().styleType() == FIRST_LETTER) {
+        updateFirstLetterStyle(block, *firstLetterRenderer);
         return;
     }
 
-    if (!is<RenderText>(*firstLetterObj))
+    if (!is<RenderText>(firstLetterRenderer))
         return;
 
-    createFirstLetterRenderer(*firstLetterContainer, downcast<RenderText>(*firstLetterObj));
+    createFirstLetterRenderer(block, downcast<RenderText>(*firstLetterRenderer));
 }
 
 };
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to