Changeset 137632 in webkit


Ignore:
Timestamp:
Dec 13, 2012 11:48:26 AM (11 years ago)
Author:
Dave Barton
Message:

Heap-use-after-free in WebCore::RenderBlock::finishDelayUpdateScrollInfo
https://bugs.webkit.org/show_bug.cgi?id=103750

Reviewed by Tony Chang.

Source/WebCore:

MathML sometimes creates and destroys renderers for descendants during layout (or even to calculate
preferred logical widths), e.g. for operator stretching. RenderBlock::finishDelayUpdateScrollInfo
must therefore leave gDelayedUpdateScrollInfoSet intact as it iterates over it, so
RenderBlock::willBeDestroyed can call gDelayedUpdateScrollInfoSet->remove(this) effectively if needed.
This also prevents duplicate entries from being added to gDelayedUpdateScrollInfoSet.

Test: mathml/mo-stretch-crash.html

  • rendering/RenderBlock.cpp:

(WebCore::RenderBlock::startDelayUpdateScrollInfo):

  • Allow gDelayedUpdateScrollInfoSet to be non-null when gDelayUpdateScrollInfo is 0 during RenderBlock::finishDelayUpdateScrollInfo.

(WebCore::RenderBlock::finishDelayUpdateScrollInfo):

  • Remove blocks from gDelayedUpdateScrollInfoSet one at a time, waiting for each block until it is about to be updated.

LayoutTests:

  • mathml/mo-stretch-crash-expected.txt: Added.
  • mathml/mo-stretch-crash.html: Added.
Location:
trunk
Files:
2 added
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r137619 r137632  
     12012-12-13  David Barton  <dbarton@mathscribe.com>
     2
     3        Heap-use-after-free in WebCore::RenderBlock::finishDelayUpdateScrollInfo
     4        https://bugs.webkit.org/show_bug.cgi?id=103750
     5
     6        Reviewed by Tony Chang.
     7
     8        * mathml/mo-stretch-crash-expected.txt: Added.
     9        * mathml/mo-stretch-crash.html: Added.
     10
    1112012-12-13  Joanmarie Diggs  <jdiggs@igalia.com>
    212
  • trunk/Source/WebCore/ChangeLog

    r137631 r137632  
     12012-12-13  David Barton  <dbarton@mathscribe.com>
     2
     3        Heap-use-after-free in WebCore::RenderBlock::finishDelayUpdateScrollInfo
     4        https://bugs.webkit.org/show_bug.cgi?id=103750
     5
     6        Reviewed by Tony Chang.
     7
     8        MathML sometimes creates and destroys renderers for descendants during layout (or even to calculate
     9        preferred logical widths), e.g. for operator stretching. RenderBlock::finishDelayUpdateScrollInfo
     10        must therefore leave gDelayedUpdateScrollInfoSet intact as it iterates over it, so
     11        RenderBlock::willBeDestroyed can call gDelayedUpdateScrollInfoSet->remove(this) effectively if needed.
     12        This also prevents duplicate entries from being added to gDelayedUpdateScrollInfoSet.
     13
     14        Test: mathml/mo-stretch-crash.html
     15
     16        * rendering/RenderBlock.cpp:
     17        (WebCore::RenderBlock::startDelayUpdateScrollInfo):
     18            - Allow gDelayedUpdateScrollInfoSet to be non-null when gDelayUpdateScrollInfo is 0 during
     19              RenderBlock::finishDelayUpdateScrollInfo.
     20        (WebCore::RenderBlock::finishDelayUpdateScrollInfo):
     21            - Remove blocks from gDelayedUpdateScrollInfoSet one at a time, waiting for each block until it is
     22              about to be updated.
     23
    1242012-12-13  Alexey Proskuryakov  <ap@apple.com>
    225
  • trunk/Source/WebCore/rendering/RenderBlock.cpp

    r137528 r137632  
    12901290void RenderBlock::startDelayUpdateScrollInfo()
    12911291{
    1292     if (gDelayUpdateScrollInfo == 0) {
    1293         ASSERT(!gDelayedUpdateScrollInfoSet);
     1292    if (!gDelayedUpdateScrollInfoSet) {
     1293        ASSERT(!gDelayUpdateScrollInfo);
    12941294        gDelayedUpdateScrollInfoSet = new DelayedUpdateScrollInfoSet;
    12951295    }
     
    13051305        ASSERT(gDelayedUpdateScrollInfoSet);
    13061306
    1307         OwnPtr<DelayedUpdateScrollInfoSet> infoSet(adoptPtr(gDelayedUpdateScrollInfoSet));
     1307        Vector<RenderBlock*> infoSet;
     1308        while (gDelayedUpdateScrollInfoSet && gDelayedUpdateScrollInfoSet->size()) {
     1309            copyToVector(*gDelayedUpdateScrollInfoSet, infoSet);
     1310            for (Vector<RenderBlock*>::iterator it = infoSet.begin(); it != infoSet.end(); ++it) {
     1311                RenderBlock* block = *it;
     1312                // |block| may have been destroyed at this point, but then it will have been removed from gDelayedUpdateScrollInfoSet.
     1313                if (gDelayedUpdateScrollInfoSet && gDelayedUpdateScrollInfoSet->contains(block)) {
     1314                    gDelayedUpdateScrollInfoSet->remove(block);
     1315                    if (block->hasOverflowClip())
     1316                        block->layer()->updateScrollInfoAfterLayout();
     1317                }
     1318            }
     1319        }
     1320        delete gDelayedUpdateScrollInfoSet;
    13081321        gDelayedUpdateScrollInfoSet = 0;
    1309 
    1310         for (DelayedUpdateScrollInfoSet::iterator it = infoSet->begin(); it != infoSet->end(); ++it) {
    1311             RenderBlock* block = *it;
    1312             if (block->hasOverflowClip()) {
    1313                 block->layer()->updateScrollInfoAfterLayout();
    1314             }
    1315         }
     1322        ASSERT(!gDelayUpdateScrollInfo);
    13161323    }
    13171324}
Note: See TracChangeset for help on using the changeset viewer.