Title: [127381] trunk
Revision
127381
Author
[email protected]
Date
2012-09-01 12:46:16 -0700 (Sat, 01 Sep 2012)

Log Message

Regression(r126763): Heap-use-after-free in WebCore::nextBreakablePosition
https://bugs.webkit.org/show_bug.cgi?id=95229

Patch by Ned Holbrook <[email protected]> on 2012-09-01
Reviewed by Dan Bernstein.

Source/WebCore:

TextLayout and LazyLineBreakIterator cache a RenderText's string during line breaking but RenderCounter
and RenderQuote can replace that string during preferred width calculation. This patch adds a non-virtual member
function to RenderText named updateTextIfNeeded() that triggers immediate string replacement by calling
the new virtual updateText() if necessary, which in turn calls computePreferredLogicalWidths(). In this way
RenderBlock::LineBreaker::nextLineBreak() can ensure a RenderText's string is current before caching it.

Test: fast/css/content/content-quotes-crash.html

* rendering/RenderBlockLineLayout.cpp:
(WebCore::dirtyLineBoxesForRenderer): Drive-by: replace existing code with the equivalent updateTextIfNeeded().
(WebCore::RenderBlock::LineBreaker::nextLineBreak): Use updateTextIfNeeded() prior to caching RenderText string.
* rendering/RenderCounter.cpp:
(WebCore::RenderCounter::updateText): Call computePreferredLogicalWidths().
(WebCore):
* rendering/RenderCounter.h:
(RenderCounter):
* rendering/RenderQuote.cpp:
(WebCore::RenderQuote::updateText): Call computePreferredLogicalWidths().
(WebCore):
* rendering/RenderQuote.h:
(RenderQuote):
* rendering/RenderText.h:
(WebCore::RenderText::updateTextIfNeeded): Only call virtual updateText() if necessary.
(RenderText):
(WebCore::RenderText::updateText): Add no-op default implementation for new virtual member function.

LayoutTests:

Ensure line breaking doesn't crash due to text of RenderText being changed.

* fast/css/content/content-quotes-crash-expected.txt: Added.
* fast/css/content/content-quotes-crash.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (127380 => 127381)


--- trunk/LayoutTests/ChangeLog	2012-09-01 19:42:46 UTC (rev 127380)
+++ trunk/LayoutTests/ChangeLog	2012-09-01 19:46:16 UTC (rev 127381)
@@ -1,3 +1,15 @@
+2012-09-01  Ned Holbrook  <[email protected]>
+
+        Regression(r126763): Heap-use-after-free in WebCore::nextBreakablePosition
+        https://bugs.webkit.org/show_bug.cgi?id=95229
+
+        Reviewed by Dan Bernstein.
+
+        Ensure line breaking doesn't crash due to text of RenderText being changed.
+
+        * fast/css/content/content-quotes-crash-expected.txt: Added.
+        * fast/css/content/content-quotes-crash.html: Added.
+
 2012-09-01  Li Yin  <[email protected]>
 
         fast/events/message-port-clone.html hits ASSERT in Debug (usually in later tests)

Added: trunk/LayoutTests/fast/css/content/content-quotes-crash-expected.txt (0 => 127381)


--- trunk/LayoutTests/fast/css/content/content-quotes-crash-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/css/content/content-quotes-crash-expected.txt	2012-09-01 19:46:16 UTC (rev 127381)
@@ -0,0 +1,3 @@
+PASS: WebKit didn't crash.
+
+a aA 

Added: trunk/LayoutTests/fast/css/content/content-quotes-crash.html (0 => 127381)


--- trunk/LayoutTests/fast/css/content/content-quotes-crash.html	                        (rev 0)
+++ trunk/LayoutTests/fast/css/content/content-quotes-crash.html	2012-09-01 19:46:16 UTC (rev 127381)
@@ -0,0 +1,16 @@
+<html>
+<head>
+    <title></title>
+    <script>
+        if (window.testRunner)
+            testRunner.dumpAsText();
+    </script>
+</head>
+<body>
+<p>
+    PASS: WebKit didn't crash.
+</p>
+<ruby><q style="column-gap:2;">a</ruby>
+    <cite style="word-break: break-all;">a<q style="text-transform:uppercase;">a<sup style="text-overflow:ellipsis;">
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (127380 => 127381)


--- trunk/Source/WebCore/ChangeLog	2012-09-01 19:42:46 UTC (rev 127380)
+++ trunk/Source/WebCore/ChangeLog	2012-09-01 19:46:16 UTC (rev 127381)
@@ -1,3 +1,36 @@
+2012-09-01  Ned Holbrook  <[email protected]>
+
+        Regression(r126763): Heap-use-after-free in WebCore::nextBreakablePosition
+        https://bugs.webkit.org/show_bug.cgi?id=95229
+
+        Reviewed by Dan Bernstein.
+
+        TextLayout and LazyLineBreakIterator cache a RenderText's string during line breaking but RenderCounter
+        and RenderQuote can replace that string during preferred width calculation. This patch adds a non-virtual member
+        function to RenderText named updateTextIfNeeded() that triggers immediate string replacement by calling
+        the new virtual updateText() if necessary, which in turn calls computePreferredLogicalWidths(). In this way
+        RenderBlock::LineBreaker::nextLineBreak() can ensure a RenderText's string is current before caching it.
+
+        Test: fast/css/content/content-quotes-crash.html
+
+        * rendering/RenderBlockLineLayout.cpp:
+        (WebCore::dirtyLineBoxesForRenderer): Drive-by: replace existing code with the equivalent updateTextIfNeeded().
+        (WebCore::RenderBlock::LineBreaker::nextLineBreak): Use updateTextIfNeeded() prior to caching RenderText string.
+        * rendering/RenderCounter.cpp:
+        (WebCore::RenderCounter::updateText): Call computePreferredLogicalWidths().
+        (WebCore):
+        * rendering/RenderCounter.h:
+        (RenderCounter):
+        * rendering/RenderQuote.cpp:
+        (WebCore::RenderQuote::updateText): Call computePreferredLogicalWidths().
+        (WebCore):
+        * rendering/RenderQuote.h:
+        (RenderQuote):
+        * rendering/RenderText.h:
+        (WebCore::RenderText::updateTextIfNeeded): Only call virtual updateText() if necessary.
+        (RenderText):
+        (WebCore::RenderText::updateText): Add no-op default implementation for new virtual member function.
+
 2012-09-01  Li Yin  <[email protected]>
 
         fast/events/message-port-clone.html hits ASSERT in Debug (usually in later tests)

Modified: trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp (127380 => 127381)


--- trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp	2012-09-01 19:42:46 UTC (rev 127380)
+++ trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp	2012-09-01 19:46:16 UTC (rev 127381)
@@ -422,9 +422,9 @@
 static inline void dirtyLineBoxesForRenderer(RenderObject* o, bool fullLayout)
 {
     if (o->isText()) {
-        if (o->preferredLogicalWidthsDirty() && (o->isCounter() || o->isQuote()))
-            toRenderText(o)->computePreferredLogicalWidths(0); // FIXME: Counters depend on this hack. No clue why. Should be investigated and removed.
-        toRenderText(o)->dirtyLineBoxes(fullLayout);
+        RenderText* renderText = toRenderText(o);
+        renderText->updateTextIfNeeded(); // FIXME: Counters depend on this hack. No clue why. Should be investigated and removed.
+        renderText->dirtyLineBoxes(fullLayout);
     } else
         toRenderInline(o)->dirtyLineBoxes(fullLayout);
 }
@@ -2433,7 +2433,8 @@
                 ASSERT(current.m_pos == t->textLength());
             }
 
-            if (renderTextInfo.m_text != t || renderTextInfo.m_lineBreakIterator.string() != t->characters()) {
+            if (renderTextInfo.m_text != t) {
+                t->updateTextIfNeeded();
                 renderTextInfo.m_text = t;
                 renderTextInfo.m_layout = f.createLayout(t, width.currentWidth(), collapseWhiteSpace);
                 renderTextInfo.m_lineBreakIterator.reset(t->characters(), t->textLength(), style->locale());

Modified: trunk/Source/WebCore/rendering/RenderCounter.cpp (127380 => 127381)


--- trunk/Source/WebCore/rendering/RenderCounter.cpp	2012-09-01 19:42:46 UTC (rev 127380)
+++ trunk/Source/WebCore/rendering/RenderCounter.cpp	2012-09-01 19:46:16 UTC (rev 127381)
@@ -538,6 +538,11 @@
     return text.impl();
 }
 
+void RenderCounter::updateText()
+{
+    computePreferredLogicalWidths(0);
+}
+
 void RenderCounter::computePreferredLogicalWidths(float lead)
 {
     setTextInternal(originalText());

Modified: trunk/Source/WebCore/rendering/RenderCounter.h (127380 => 127381)


--- trunk/Source/WebCore/rendering/RenderCounter.h	2012-09-01 19:42:46 UTC (rev 127380)
+++ trunk/Source/WebCore/rendering/RenderCounter.h	2012-09-01 19:46:16 UTC (rev 127381)
@@ -48,6 +48,7 @@
     virtual bool isCounter() const;
     virtual PassRefPtr<StringImpl> originalText() const;
     
+    virtual void updateText() OVERRIDE;
     virtual void computePreferredLogicalWidths(float leadWidth);
 
     // Removes the reference to the CounterNode associated with this renderer.

Modified: trunk/Source/WebCore/rendering/RenderQuote.cpp (127380 => 127381)


--- trunk/Source/WebCore/rendering/RenderQuote.cpp	2012-09-01 19:42:46 UTC (rev 127380)
+++ trunk/Source/WebCore/rendering/RenderQuote.cpp	2012-09-01 19:46:16 UTC (rev 127381)
@@ -243,6 +243,11 @@
     return StringImpl::empty();
 }
 
+void RenderQuote::updateText()
+{
+    computePreferredLogicalWidths(0);
+}
+
 void RenderQuote::computePreferredLogicalWidths(float lead)
 {
     if (!m_attached)

Modified: trunk/Source/WebCore/rendering/RenderQuote.h (127380 => 127381)


--- trunk/Source/WebCore/rendering/RenderQuote.h	2012-09-01 19:42:46 UTC (rev 127380)
+++ trunk/Source/WebCore/rendering/RenderQuote.h	2012-09-01 19:46:16 UTC (rev 127381)
@@ -43,6 +43,8 @@
     virtual const char* renderName() const OVERRIDE { return "RenderQuote"; };
     virtual bool isQuote() const OVERRIDE { return true; };
     virtual PassRefPtr<StringImpl> originalText() const OVERRIDE;
+
+    virtual void updateText() OVERRIDE;
     virtual void computePreferredLogicalWidths(float leadWidth) OVERRIDE;
 
     // We don't override insertedIntoTree to call attachQuote() as it would be attached

Modified: trunk/Source/WebCore/rendering/RenderText.h (127380 => 127381)


--- trunk/Source/WebCore/rendering/RenderText.h	2012-09-01 19:42:46 UTC (rev 127380)
+++ trunk/Source/WebCore/rendering/RenderText.h	2012-09-01 19:46:16 UTC (rev 127381)
@@ -45,6 +45,12 @@
 
     virtual PassRefPtr<StringImpl> originalText() const;
 
+    void updateTextIfNeeded()
+    {
+        if (preferredLogicalWidthsDirty())
+            updateText();
+    }
+
     void extractTextBox(InlineTextBox*);
     void attachTextBox(InlineTextBox*);
     void removeTextBox(InlineTextBox*);
@@ -139,6 +145,7 @@
     virtual void styleWillChange(StyleDifference, const RenderStyle*) { }
     virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
 
+    virtual void updateText() { }
     virtual void setTextInternal(PassRefPtr<StringImpl>);
     virtual UChar previousCharacter() const;
     
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to