Changeset 51169 in webkit


Ignore:
Timestamp:
Nov 18, 2009 7:15:49 PM (14 years ago)
Author:
rolandsteiner@chromium.org
Message:

WebCore: Bug 31574 - Crashing bug when removing <ruby> element
(https://bugs.webkit.org/show_bug.cgi?id=31574)

Reviewed by Darin Adler.

Cause of the bug:
1.) RenderBlock::destroy() of the RenderRubyRun called destroyLeftoverChildren()
2.) that called destroy() of the RenderRubyBase(), which in RenderObject::destroy() calls remove()
3.) remove() is being redirected as parent()->removeChild() in RenderObject.h
4.) this triggers the special handling of child removal in RenderRubyRun that

causes it to destroy itself

5.) On returning from all this the renderer crashes when accessing a member

or virtual function on this now illegal object.

I therefore added a flag that tracks if the ruby run is being destroyed.
If so, avoid doing the special handling in removeChild that caused this.
It's not the most elegant solution, but the easiest to implement without
touching unrelated code. Also, it's self-documenting.

Test: fast/ruby/ruby-remove.html

  • rendering/RenderRubyRun.cpp:

(WebCore::RenderRubyRun::RenderRubyRun):
(WebCore::RenderRubyRun::destroy):
(WebCore::RenderRubyRun::removeChild):

  • rendering/RenderRubyRun.h:

LayoutTests: Bug 31574 - Crashing bug when removing <ruby> element
(https://bugs.webkit.org/show_bug.cgi?id=31574)

Reviewed by Darin Adler.

Layout test to verify it no longer crashes when the <ruby> element
is being removed.

  • fast/ruby/ruby-remove-expected.txt: Added.
  • fast/ruby/ruby-remove.html: Added.
Location:
trunk
Files:
2 added
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r51163 r51169  
     12009-11-19  Roland Steiner  <rolandsteiner@chromium.org>
     2
     3        Reviewed by Darin Adler.
     4
     5        Bug 31574 -  Crashing bug when removing <ruby> element
     6        (https://bugs.webkit.org/show_bug.cgi?id=31574)
     7       
     8        Layout test to verify it no longer crashes when the <ruby> element
     9        is being removed.
     10
     11        * fast/ruby/ruby-remove-expected.txt: Added.
     12        * fast/ruby/ruby-remove.html: Added.
     13
    1142009-11-18  Kent Tamura  <tkent@chromium.org>
    215
  • trunk/WebCore/ChangeLog

    r51166 r51169  
     12009-11-19  Roland Steiner  <rolandsteiner@chromium.org>
     2
     3        Reviewed by Darin Adler.
     4
     5        Bug 31574 -  Crashing bug when removing <ruby> element
     6        (https://bugs.webkit.org/show_bug.cgi?id=31574)
     7
     8        Cause of the bug:
     9        1.) RenderBlock::destroy() of the RenderRubyRun called destroyLeftoverChildren()
     10        2.) that called destroy() of the RenderRubyBase(), which in RenderObject::destroy() calls remove()
     11        3.) remove() is being redirected as parent()->removeChild() in RenderObject.h
     12        4.) this triggers the special handling of child removal in RenderRubyRun that
     13            causes it to destroy itself
     14        5.) On returning from all this the renderer crashes when accessing a member
     15            or virtual function on this now illegal object.
     16
     17        I therefore added a flag that tracks if the ruby run is being destroyed.
     18        If so, avoid doing the special handling in removeChild that caused this.
     19        It's not the most elegant solution, but the easiest to implement without
     20        touching unrelated code. Also, it's self-documenting.
     21
     22        Test: fast/ruby/ruby-remove.html
     23
     24        * rendering/RenderRubyRun.cpp:
     25        (WebCore::RenderRubyRun::RenderRubyRun):
     26        (WebCore::RenderRubyRun::destroy):
     27        (WebCore::RenderRubyRun::removeChild):
     28        * rendering/RenderRubyRun.h:
     29
    1302009-11-18  Laszlo Gombos  <laszlo.1.gombos@nokia.com>
    231
  • trunk/WebCore/rendering/RenderRubyRun.cpp

    r50397 r51169  
    4242RenderRubyRun::RenderRubyRun(Node* node)
    4343    : RenderBlock(node)
     44    , m_beingDestroyed(false)
    4445{
    4546    setReplaced(true);
     
    4950RenderRubyRun::~RenderRubyRun()
    5051{
     52}
     53
     54void RenderRubyRun::destroy()
     55{
     56    // Mark if the run is being destroyed to avoid trouble in removeChild().
     57    m_beingDestroyed = true;
     58    RenderBlock::destroy();
    5159}
    5260
     
    156164    // If the child is a ruby text, then merge the ruby base with the base of
    157165    // the right sibling run, if possible.
    158     if (!documentBeingDestroyed() && child->isRubyText()) {
     166    if (!m_beingDestroyed && !documentBeingDestroyed() && child->isRubyText()) {
    159167        RenderRubyBase* base = rubyBase();
    160168        RenderObject* rightNeighbour = nextSibling();
     
    170178    RenderBlock::removeChild(child);
    171179
    172     if (!documentBeingDestroyed()) {
     180    if (!m_beingDestroyed && !documentBeingDestroyed()) {
    173181        // Check if our base (if any) is now empty. If so, destroy it.
    174182        RenderBlock* base = rubyBase();
     
    179187        }
    180188
    181         // If any of the above leaves the run empty, destroy it as well
     189        // If any of the above leaves the run empty, destroy it as well.
    182190        if (isEmpty()) {
    183191            parent()->removeChild(this);
  • trunk/WebCore/rendering/RenderRubyRun.h

    r50397 r51169  
    4747    virtual ~RenderRubyRun();
    4848
     49    virtual void destroy();
     50
    4951    virtual const char* renderName() const { return "RenderRubyRun (anonymous)"; }
    5052
     
    6971protected:
    7072    RenderRubyBase* createRubyBase() const;
     73   
     74private:
     75    bool m_beingDestroyed;
    7176};
    7277
Note: See TracChangeset for help on using the changeset viewer.