Title: [112200] trunk
Revision
112200
Author
[email protected]
Date
2012-03-26 20:16:34 -0700 (Mon, 26 Mar 2012)

Log Message

Assert failure from capitalized RenderTextFragment
https://bugs.webkit.org/show_bug.cgi?id=82096

Patch by Ken Buchanan <[email protected]> on 2012-03-26
Reviewed by Ryosuke Niwa.

Source/WebCore:

The cause of this bug was the call to RenderTextFragment::setTextInternal
resulting from a style change from RenderObject::addChild. The idea here
is to better separate the code path for transforming existing text from
the code path for replacing the underlying text of a node. For
RenderTextFragment this has to be clear because only in the latter case
does the first-letter get reset.

* rendering/RenderObject.cpp:
(WebCore::RenderObject::addChild): Added call to transformText
* rendering/RenderText.cpp:
(WebCore::RenderText::styleDidChange): Added call to transformText
(WebCore::RenderText::transformText): Added
* rendering/RenderText.h:
(WebCore::RenderText::setText): Changed to virtual so RenderTextFragment can override
(WebCore::RenderText::transformText): Added
* rendering/RenderTextFragment.cpp:
(WebCore::RenderTextFragment::styleDidChange): Removed references to
m_allowFragmentReset which was the previous approach to separating the
code paths
(WebCore::RenderTextFragment::setTextInternal): Deleted
(WebCore::RenderTextFragment::setText): Added with most of logic that was
previously in setTextInternal
(WebCore::RenderTextFragment::transformText): Added
* rendering/RenderTextFragment.h:
(WebCore::RenderTextFragment::setText): Added
(WebCore::RenderTextFragment::transformText): Added
(WebCore::RenderTextFragment::setTextInternal): Deleted

LayoutTests:

Test that exercises failure condition in bug 82096.

* fast/css/first-letter-capitalized-edit-select-crash-expected.txt: Added
* fast/css/first-letter-capitalized-edit-select-crash.html: Added

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (112199 => 112200)


--- trunk/LayoutTests/ChangeLog	2012-03-27 02:58:28 UTC (rev 112199)
+++ trunk/LayoutTests/ChangeLog	2012-03-27 03:16:34 UTC (rev 112200)
@@ -1,3 +1,15 @@
+2012-03-26  Ken Buchanan  <[email protected]>
+
+        Assert failure from capitalized RenderTextFragment
+        https://bugs.webkit.org/show_bug.cgi?id=82096
+
+        Reviewed by Ryosuke Niwa.
+
+        Test that exercises failure condition in bug 82096.
+
+        * fast/css/first-letter-capitalized-edit-select-crash-expected.txt: Added
+        * fast/css/first-letter-capitalized-edit-select-crash.html: Added
+
 2012-03-26  Shinya Kawanaka  <[email protected]>
 
         Triggers assertion if dragging from outside of <meter> in a shadow tree to inside of it.

Added: trunk/LayoutTests/fast/css/first-letter-capitalized-edit-select-crash-expected.txt (0 => 112200)


--- trunk/LayoutTests/fast/css/first-letter-capitalized-edit-select-crash-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/css/first-letter-capitalized-edit-select-crash-expected.txt	2012-03-27 03:16:34 UTC (rev 112200)
@@ -0,0 +1,3 @@
+Pass if no crash or assert in debug
+
+

Added: trunk/LayoutTests/fast/css/first-letter-capitalized-edit-select-crash.html (0 => 112200)


--- trunk/LayoutTests/fast/css/first-letter-capitalized-edit-select-crash.html	                        (rev 0)
+++ trunk/LayoutTests/fast/css/first-letter-capitalized-edit-select-crash.html	2012-03-27 03:16:34 UTC (rev 112200)
@@ -0,0 +1,20 @@
+<style>
+.writable{-webkit-user-modify:read-write;}
+.list{content:normal;display:list-item;}
+*:first-letter{stroke-linecap:round;}
+*:only-child{-webkit-font-variant-ligatures:common-ligatures;text-transform:capitalize;</style>
+</style>
+Pass if no crash or assert in debug
+<span class="writable" id="span">
+<label class="list">
+<code>
+<object></object>
+</code></label></span>
+<script>
+window._onload_=function()
+{
+    document.getElementById('span').focus();
+    if (window.layoutTestController)
+        layoutTestController.dumpAsText();
+};
+</script>

Modified: trunk/Source/WebCore/ChangeLog (112199 => 112200)


--- trunk/Source/WebCore/ChangeLog	2012-03-27 02:58:28 UTC (rev 112199)
+++ trunk/Source/WebCore/ChangeLog	2012-03-27 03:16:34 UTC (rev 112200)
@@ -1,3 +1,38 @@
+2012-03-26  Ken Buchanan  <[email protected]>
+
+        Assert failure from capitalized RenderTextFragment
+        https://bugs.webkit.org/show_bug.cgi?id=82096
+
+        Reviewed by Ryosuke Niwa.
+
+        The cause of this bug was the call to RenderTextFragment::setTextInternal
+        resulting from a style change from RenderObject::addChild. The idea here
+        is to better separate the code path for transforming existing text from
+        the code path for replacing the underlying text of a node. For
+        RenderTextFragment this has to be clear because only in the latter case
+        does the first-letter get reset.
+
+        * rendering/RenderObject.cpp:
+        (WebCore::RenderObject::addChild): Added call to transformText
+        * rendering/RenderText.cpp:
+        (WebCore::RenderText::styleDidChange): Added call to transformText
+        (WebCore::RenderText::transformText): Added
+        * rendering/RenderText.h:
+        (WebCore::RenderText::setText): Changed to virtual so RenderTextFragment can override
+        (WebCore::RenderText::transformText): Added
+        * rendering/RenderTextFragment.cpp:
+        (WebCore::RenderTextFragment::styleDidChange): Removed references to
+        m_allowFragmentReset which was the previous approach to separating the
+        code paths
+        (WebCore::RenderTextFragment::setTextInternal): Deleted
+        (WebCore::RenderTextFragment::setText): Added with most of logic that was
+        previously in setTextInternal
+        (WebCore::RenderTextFragment::transformText): Added
+        * rendering/RenderTextFragment.h:
+        (WebCore::RenderTextFragment::setText): Added
+        (WebCore::RenderTextFragment::transformText): Added
+        (WebCore::RenderTextFragment::setTextInternal): Deleted
+
 2012-03-26  Adam Klein  <[email protected]>
 
         Always set V8 wrappers via V8DOMWrapper::setJSWrapperFor* instead of WeakReferenceMap::set()

Modified: trunk/Source/WebCore/rendering/RenderObject.cpp (112199 => 112200)


--- trunk/Source/WebCore/rendering/RenderObject.cpp	2012-03-27 02:58:28 UTC (rev 112199)
+++ trunk/Source/WebCore/rendering/RenderObject.cpp	2012-03-27 03:16:34 UTC (rev 112200)
@@ -332,11 +332,8 @@
         children->insertChildNode(this, newChild, beforeChild);
     }
 
-    if (newChild->isText() && newChild->style()->textTransform() == CAPITALIZE) {
-        RefPtr<StringImpl> textToTransform = toRenderText(newChild)->originalText();
-        if (textToTransform)
-            toRenderText(newChild)->setText(textToTransform.release(), true);
-    }
+    if (newChild->isText() && newChild->style()->textTransform() == CAPITALIZE)
+        toRenderText(newChild)->transformText();
 
     // SVG creates renderers for <g display="none">, as SVG requires children of hidden
     // <g>s to have renderers - at least that's how our implementation works. Consider:

Modified: trunk/Source/WebCore/rendering/RenderText.cpp (112199 => 112200)


--- trunk/Source/WebCore/rendering/RenderText.cpp	2012-03-27 02:58:28 UTC (rev 112199)
+++ trunk/Source/WebCore/rendering/RenderText.cpp	2012-03-27 03:16:34 UTC (rev 112200)
@@ -201,10 +201,8 @@
 
     ETextTransform oldTransform = oldStyle ? oldStyle->textTransform() : TTNONE;
     ETextSecurity oldSecurity = oldStyle ? oldStyle->textSecurity() : TSNONE;
-    if (needsResetText || oldTransform != newStyle->textTransform() || oldSecurity != newStyle->textSecurity()) {
-        if (RefPtr<StringImpl> textToTransform = originalText())
-            setText(textToTransform.release(), true);
-    }
+    if (needsResetText || oldTransform != newStyle->textTransform() || oldSecurity != newStyle->textSecurity()) 
+        transformText();
 }
 
 void RenderText::removeAndDestroyTextBoxes()
@@ -1238,6 +1236,12 @@
     setText(text, force);
 }
 
+void RenderText::transformText()
+{
+    if (RefPtr<StringImpl> textToTransform = originalText())
+        setText(textToTransform.release(), true);
+}
+
 static inline bool isInlineFlowOrEmptyText(const RenderObject* o)
 {
     if (o->isRenderInline())

Modified: trunk/Source/WebCore/rendering/RenderText.h (112199 => 112200)


--- trunk/Source/WebCore/rendering/RenderText.h	2012-03-27 02:58:28 UTC (rev 112199)
+++ trunk/Source/WebCore/rendering/RenderText.h	2012-03-27 03:16:34 UTC (rev 112200)
@@ -89,9 +89,11 @@
     float firstRunX() const;
     float firstRunY() const;
 
-    void setText(PassRefPtr<StringImpl>, bool force = false);
+    virtual void setText(PassRefPtr<StringImpl>, bool force = false);
     void setTextWithOffset(PassRefPtr<StringImpl>, unsigned offset, unsigned len, bool force = false);
 
+    virtual void transformText();
+
     virtual bool canBeSelectionLeaf() const { return true; }
     virtual void setSelectionState(SelectionState s);
     virtual LayoutRect selectionRectForRepaint(RenderBoxModelObject* repaintContainer, bool clipToVisibleContent = true);
@@ -160,7 +162,6 @@
     bool isAllASCII() const { return m_isAllASCII; }
     void updateNeedsTranscoding();
 
-    inline void transformText(String&) const;
     void secureText(UChar mask);
 
     float m_minWidth; // here to minimize padding in 64-bit.

Modified: trunk/Source/WebCore/rendering/RenderTextFragment.cpp (112199 => 112200)


--- trunk/Source/WebCore/rendering/RenderTextFragment.cpp	2012-03-27 02:58:28 UTC (rev 112199)
+++ trunk/Source/WebCore/rendering/RenderTextFragment.cpp	2012-03-27 03:16:34 UTC (rev 112200)
@@ -33,7 +33,6 @@
     , m_start(startOffset)
     , m_end(length)
     , m_firstLetter(0)
-    , m_allowFragmentReset(true)
 {
 }
 
@@ -43,7 +42,6 @@
     , m_end(str ? str->length() : 0)
     , m_contentString(str)
     , m_firstLetter(0)
-    , m_allowFragmentReset(true)
 {
 }
 
@@ -62,9 +60,7 @@
 
 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);
@@ -79,25 +75,30 @@
     RenderText::willBeDestroyed();
 }
 
-void RenderTextFragment::setTextInternal(PassRefPtr<StringImpl> text)
+void RenderTextFragment::setText(PassRefPtr<StringImpl> text, bool force)
 {
-    RenderText::setTextInternal(text);
+    RenderText::setText(text, force);
 
-    if (m_allowFragmentReset) {
-        m_start = 0;
-        m_end = textLength();
-        if (m_firstLetter) {
-            ASSERT(!m_contentString);
-            m_firstLetter->destroy();
-            m_firstLetter = 0;
-            if (Node* t = node()) {
-                ASSERT(!t->renderer());
-                t->setRenderer(this);
-            }
+    m_start = 0;
+    m_end = textLength();
+    if (m_firstLetter) {
+        ASSERT(!m_contentString);
+        m_firstLetter->destroy();
+        m_firstLetter = 0;
+        if (Node* t = node()) {
+            ASSERT(!t->renderer());
+            t->setRenderer(this);
         }
     }
 }
 
+void RenderTextFragment::transformText()
+{
+    // Don't reset first-letter here because we are only transforming the truncated fragment.
+    if (RefPtr<StringImpl> textToTransform = originalText())
+        RenderText::setText(textToTransform.release(), true);
+}
+
 UChar RenderTextFragment::previousCharacter() const
 {
     if (start()) {

Modified: trunk/Source/WebCore/rendering/RenderTextFragment.h (112199 => 112200)


--- trunk/Source/WebCore/rendering/RenderTextFragment.h	2012-03-27 02:58:28 UTC (rev 112199)
+++ trunk/Source/WebCore/rendering/RenderTextFragment.h	2012-03-27 03:16:34 UTC (rev 112200)
@@ -50,13 +50,16 @@
     StringImpl* contentString() const { return m_contentString.get(); }
     virtual PassRefPtr<StringImpl> originalText() const;
 
+    virtual void setText(PassRefPtr<StringImpl>, bool force = false) OVERRIDE;
+
+    virtual void transformText() OVERRIDE;
+
 protected:
     virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
 
 private:
     virtual void willBeDestroyed();
 
-    virtual void setTextInternal(PassRefPtr<StringImpl>);
     virtual UChar previousCharacter() const;
     RenderBlock* blockForAccompanyingFirstLetter() const;
 
@@ -64,7 +67,6 @@
     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