Title: [110332] trunk
Revision
110332
Author
[email protected]
Date
2012-03-09 14:36:10 -0800 (Fri, 09 Mar 2012)

Log Message

Crash due to inserting letter into div with first-letter
https://bugs.webkit.org/show_bug.cgi?id=78534

Patch by Ken Buchanan <[email protected]> on 2012-03-09
Reviewed by David Hyatt.

Source/WebCore:

This fixes an issue in RenderTextFragment with setTextInternal
getting called with different intents. While most calls to it
are intended to change the underlying DOM node string, it can
also be called as a result of styleDidChange just for transforms
on the substring text fragment. This adds a mechanism for internal
callers to specify if the internal text is being updated without
a DOM node text change.

* rendering/RenderTextFragment.cpp:
(WebCore::RenderTextFragment::styleDidChange)
(WebCore::RenderTextFragment::setTextInternal)
* rendering/RenderTextFragment.h:
(WebCore::RenderTextFragment)

LayoutTests:

Test case to exercise the crashing condition in bug 78534. It inserts
a character in a first-letter div to induce an invalid RenderTextFragment
state.

* editing/inserting/insert-character-in-first-letter-crash-expected.txt: Added
* editing/inserting/insert-character-in-first-letter-crash.html: Added

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (110331 => 110332)


--- trunk/LayoutTests/ChangeLog	2012-03-09 22:31:55 UTC (rev 110331)
+++ trunk/LayoutTests/ChangeLog	2012-03-09 22:36:10 UTC (rev 110332)
@@ -1,3 +1,17 @@
+2012-03-09  Ken Buchanan  <[email protected]>
+
+        Crash due to inserting letter into div with first-letter
+        https://bugs.webkit.org/show_bug.cgi?id=78534
+
+        Reviewed by David Hyatt.
+
+        Test case to exercise the crashing condition in bug 78534. It inserts
+        a character in a first-letter div to induce an invalid RenderTextFragment
+        state.
+
+        * editing/inserting/insert-character-in-first-letter-crash-expected.txt: Added
+        * editing/inserting/insert-character-in-first-letter-crash.html: Added
+
 2012-03-09  Gavin Barraclough  <[email protected]>
 
         REGRESSION: Date.parse("Tue Nov 23 20:40:05 2010 GMT") returns NaN

Added: trunk/LayoutTests/editing/inserting/insert-character-in-first-letter-crash-expected.txt (0 => 110332)


--- trunk/LayoutTests/editing/inserting/insert-character-in-first-letter-crash-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/editing/inserting/insert-character-in-first-letter-crash-expected.txt	2012-03-09 22:36:10 UTC (rev 110332)
@@ -0,0 +1,2 @@
+◦◦
+PASS if no assert or crash in debug.

Added: trunk/LayoutTests/editing/inserting/insert-character-in-first-letter-crash.html (0 => 110332)


--- trunk/LayoutTests/editing/inserting/insert-character-in-first-letter-crash.html	                        (rev 0)
+++ trunk/LayoutTests/editing/inserting/insert-character-in-first-letter-crash.html	2012-03-09 22:36:10 UTC (rev 110332)
@@ -0,0 +1,35 @@
+<html>
+  <head>
+    <style>
+      #div1 {
+        -webkit-text-security: circle;
+      }
+      #div1::first-letter {
+        display: table-row-group;
+      }
+      #div2 {
+        display: table;
+      }
+      #div2:last-child {
+        display: table-row;
+      }
+    </style>
+    <script>
+      window._onload_ = function() {
+        var div1 = document.getElementById('div1');
+        document.designMode='on';
+        document.execCommand('selectall');
+        document.execCommand('insertText', false, 'Z');
+        document.execCommand('Undo');
+        div1.appendChild(document.createElement('div'));
+        document.execCommand('selectall');
+
+        document.body.appendChild(document.createTextNode("PASS if no assert or crash in debug."));
+
+        if (window.layoutTestController)
+            layoutTestController.dumpAsText();
+     }
+    </script>
+  </head>
+  <body><div id=div1>AB<div id=div2></div></div></body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (110331 => 110332)


--- trunk/Source/WebCore/ChangeLog	2012-03-09 22:31:55 UTC (rev 110331)
+++ trunk/Source/WebCore/ChangeLog	2012-03-09 22:36:10 UTC (rev 110332)
@@ -1,3 +1,24 @@
+2012-03-09  Ken Buchanan  <[email protected]>
+
+        Crash due to inserting letter into div with first-letter
+        https://bugs.webkit.org/show_bug.cgi?id=78534
+
+        Reviewed by David Hyatt.
+
+        This fixes an issue in RenderTextFragment with setTextInternal
+        getting called with different intents. While most calls to it
+        are intended to change the underlying DOM node string, it can
+        also be called as a result of styleDidChange just for transforms
+        on the substring text fragment. This adds a mechanism for internal
+        callers to specify if the internal text is being updated without
+        a DOM node text change.
+
+        * rendering/RenderTextFragment.cpp:
+        (WebCore::RenderTextFragment::styleDidChange)
+        (WebCore::RenderTextFragment::setTextInternal)
+        * rendering/RenderTextFragment.h:
+        (WebCore::RenderTextFragment)
+
 2012-03-09  Chris Rogers  <[email protected]>
 
         Fix uninitialized variable in DynamicsCompressor

Modified: trunk/Source/WebCore/rendering/RenderTextFragment.cpp (110331 => 110332)


--- trunk/Source/WebCore/rendering/RenderTextFragment.cpp	2012-03-09 22:31:55 UTC (rev 110331)
+++ trunk/Source/WebCore/rendering/RenderTextFragment.cpp	2012-03-09 22:36:10 UTC (rev 110332)
@@ -33,6 +33,7 @@
     , m_start(startOffset)
     , m_end(length)
     , m_firstLetter(0)
+    , m_allowFragmentReset(true)
 {
 }
 
@@ -42,6 +43,7 @@
     , m_end(str ? str->length() : 0)
     , m_contentString(str)
     , m_firstLetter(0)
+    , m_allowFragmentReset(true)
 {
 }
 
@@ -60,7 +62,9 @@
 
 void RenderTextFragment::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
 {
+    m_allowFragmentReset = false;
     RenderText::styleDidChange(diff, oldStyle);
+    m_allowFragmentReset = true;
 
     if (RenderBlock* block = blockForAccompanyingFirstLetter()) {
         block->style()->removeCachedPseudoStyle(FIRST_LETTER);
@@ -78,15 +82,18 @@
 void RenderTextFragment::setTextInternal(PassRefPtr<StringImpl> text)
 {
     RenderText::setTextInternal(text);
-    if (m_firstLetter) {
-        ASSERT(!m_contentString);
-        m_firstLetter->destroy();
-        m_firstLetter = 0;
+
+    if (m_allowFragmentReset) {
         m_start = 0;
         m_end = textLength();
-        if (Node* t = node()) {
-            ASSERT(!t->renderer());
-            t->setRenderer(this);
+        if (m_firstLetter) {
+            ASSERT(!m_contentString);
+            m_firstLetter->destroy();
+            m_firstLetter = 0;
+            if (Node* t = node()) {
+                ASSERT(!t->renderer());
+                t->setRenderer(this);
+            }
         }
     }
 }

Modified: trunk/Source/WebCore/rendering/RenderTextFragment.h (110331 => 110332)


--- trunk/Source/WebCore/rendering/RenderTextFragment.h	2012-03-09 22:31:55 UTC (rev 110331)
+++ trunk/Source/WebCore/rendering/RenderTextFragment.h	2012-03-09 22:36:10 UTC (rev 110332)
@@ -62,6 +62,7 @@
     unsigned m_end;
     RefPtr<StringImpl> m_contentString;
     RenderObject* m_firstLetter;
+    bool m_allowFragmentReset;
 };
 
 inline RenderTextFragment* toRenderTextFragment(RenderObject* object)
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to