⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 179691 in webkit


Ignore:
Timestamp:
Feb 5, 2015, 8:50:44 AM (12 years ago)
Author:
Alan Bujtas
Message:

Do not destroy RenderQuote's text fragment child when quotation mark string is changing.
​https://bugs.webkit.org/show_bug.cgi?id=141271
rdar://problem/18169375

Reviewed by Antti Koivisto.

Similar approach as ​https://codereview.chromium.org/679593004/

This patch ensures that laying out a RenderQuote does not force a sibling RenderQuote's
child renderer(RenderText) to be destroyed.
BreakingContext holds a pointer to the next renderer on the line (BreakingContext::m_nextObject).
While laying out the line, initiated by BreakingContext, placing the current renderer could end up destroying the "next" renderer.
This happens when the pseudo after quotation mark(RenderQuote) becomes floated, the sibling <q>'s pseudo
before text needs to be changed (from " to ') so that we don't end up with 2 sets of the same opening
strings.
The fix is to reuse the RenderTextFragment object instead of destroy/recreate it.

Source/WebCore:

Test: fast/css/content/quote-crash-when-floating.html

  • rendering/RenderQuote.cpp:

(WebCore::RenderQuote::RenderQuote):
(WebCore::fragmentChild):
(WebCore::RenderQuote::updateText):

  • rendering/RenderQuote.h:
  • rendering/RenderTextFragment.cpp:

(WebCore::RenderTextFragment::setText):
(WebCore::RenderTextFragment::setContentString):

  • rendering/RenderTextFragment.h:

LayoutTests:

  • fast/css/content/quote-crash-when-floating-expected.txt: Added.
  • fast/css/content/quote-crash-when-floating.html: Added.
Location:
trunk
Files:
2 added
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r179688 r179691  
     12015-02-05  Zalan Bujtas  <zalan@apple.com>
     2
     3        Do not destroy RenderQuote's text fragment child when quotation mark string is changing.
     4        https://bugs.webkit.org/show_bug.cgi?id=141271
     5        rdar://problem/18169375
     6
     7        Reviewed by Antti Koivisto.
     8
     9        Similar approach as https://codereview.chromium.org/679593004/
     10
     11        This patch ensures that laying out a RenderQuote does not force a sibling RenderQuote's
     12        child renderer(RenderText) to be destroyed.
     13        BreakingContext holds a pointer to the next renderer on the line (BreakingContext::m_nextObject).
     14        While laying out the line, initiated by BreakingContext, placing the current renderer could end up destroying the "next" renderer.
     15        This happens when the pseudo after quotation mark(RenderQuote) becomes floated, the sibling <q>'s pseudo
     16        before text needs to be changed (from " to ') so that we don't end up with 2 sets of the same opening
     17        strings.
     18        The fix is to reuse the RenderTextFragment object instead of destroy/recreate it.
     19
     20        * fast/css/content/quote-crash-when-floating-expected.txt: Added.
     21        * fast/css/content/quote-crash-when-floating.html: Added.
     22
    1232015-02-05  Gyuyoung Kim  <gyuyoung.kim@samsung.com>
    224
  • trunk/Source/WebCore/ChangeLog

    r179689 r179691  
     12015-02-05  Zalan Bujtas  <zalan@apple.com>
     2
     3        Do not destroy RenderQuote's text fragment child when quotation mark string is changing.
     4        https://bugs.webkit.org/show_bug.cgi?id=141271
     5        rdar://problem/18169375
     6
     7        Reviewed by Antti Koivisto.
     8
     9        Similar approach as https://codereview.chromium.org/679593004/
     10
     11        This patch ensures that laying out a RenderQuote does not force a sibling RenderQuote's
     12        child renderer(RenderText) to be destroyed.
     13        BreakingContext holds a pointer to the next renderer on the line (BreakingContext::m_nextObject).
     14        While laying out the line, initiated by BreakingContext, placing the current renderer could end up destroying the "next" renderer.
     15        This happens when the pseudo after quotation mark(RenderQuote) becomes floated, the sibling <q>'s pseudo
     16        before text needs to be changed (from " to ') so that we don't end up with 2 sets of the same opening
     17        strings.
     18        The fix is to reuse the RenderTextFragment object instead of destroy/recreate it.
     19
     20        Test: fast/css/content/quote-crash-when-floating.html
     21
     22        * rendering/RenderQuote.cpp:
     23        (WebCore::RenderQuote::RenderQuote):
     24        (WebCore::fragmentChild):
     25        (WebCore::RenderQuote::updateText):
     26        * rendering/RenderQuote.h:
     27        * rendering/RenderTextFragment.cpp:
     28        (WebCore::RenderTextFragment::setText):
     29        (WebCore::RenderTextFragment::setContentString):
     30        * rendering/RenderTextFragment.h:
     31
    1322015-02-04  Dean Jackson  <dino@apple.com>
    233
  • trunk/Source/WebCore/rendering/RenderQuote.cpp

    r177259 r179691  
    3535    : RenderInline(document, WTF::move(style))
    3636    , m_type(quote)
    37     , m_depth(-1)
    38     , m_next(0)
    39     , m_previous(0)
    40     , m_isAttached(false)
     37    , m_text(emptyString())
    4138{
    4239}
    … …  
    334331}
    335332
     333static RenderTextFragment* fragmentChild(RenderObject* lastChild)
     334{
     335    if (!lastChild)
     336        return nullptr;
     337
     338    if (!is<RenderTextFragment>(lastChild))
     339        return nullptr;
     340
     341    return downcast<RenderTextFragment>(lastChild);
     342}
     343
    336344void RenderQuote::updateText()
    337345{
    … …  
    339347    if (m_text == text)
    340348        return;
    341 
    342     while (RenderObject* child = lastChild())
    343         child->destroy();
    344 
    345     if (text == emptyString() || text == String()) {
    346         m_text = String();
     349    m_text = text;
     350    // Start from the end of the child list because, if we've had a first-letter
     351    // renderer inserted then the remaining text will be at the end.
     352    if (auto* fragment = fragmentChild(lastChild())) {
     353        fragment->setContentString(m_text);
    347354        return;
    348355    }
    349 
    350     m_text = text;
    351 
    352     RenderTextFragment* fragment = new RenderTextFragment(document(), m_text.impl());
    353     addChild(fragment);
     356    addChild(new RenderTextFragment(document(), m_text));
    354357}
    355358
  • trunk/Source/WebCore/rendering/RenderQuote.h

    r177259 r179691  
    4747    void updateDepth();
    4848
    49     QuoteType m_type;
    50     int m_depth;
    51     RenderQuote* m_next;
    52     RenderQuote* m_previous;
    53     bool m_isAttached;
     49    const QuoteType m_type;
     50    int m_depth { -1 };
     51    RenderQuote* m_next { nullptr };
     52    RenderQuote* m_previous { nullptr };
     53    bool m_isAttached { false };
    5454    String m_text;
    5555};
  • trunk/Source/WebCore/rendering/RenderTextFragment.cpp

    r160966 r179691  
    8989    if (!m_firstLetter)
    9090        return;
    91     ASSERT(!m_contentString);
    9291    m_firstLetter->destroy();
    9392    m_firstLetter = 0;
    … …  
    120119}
    121120
     121void RenderTextFragment::setContentString(const String& text)
     122{
     123    m_contentString = text;
     124    setText(text);
     125}
     126
    122127} // namespace WebCore
  • trunk/Source/WebCore/rendering/RenderTextFragment.h

    r175084 r179691  
    5050    RenderBlock* blockForAccompanyingFirstLetter();
    5151
     52    void setContentString(const String& text);
    5253    StringImpl* contentString() const { return m_contentString.impl(); }
    5354
Note: See TracChangeset for help on using the changeset viewer.