Bug 855898 - Limit ProcessChildren recursion depth to avoid exhausting stack space and crashing. r=bzbarsky

This commit is contained in:
Mats Palmgren 2013-04-23 13:37:18 +02:00
parent ce9b893bf3
commit 6c2ebcbbff
2 changed files with 21 additions and 3 deletions

View File

@ -11,11 +11,11 @@
#include "nsCSSFrameConstructor.h"
#include "mozilla/AutoRestore.h"
#include "mozilla/DebugOnly.h"
#include "mozilla/dom/HTMLSelectElement.h"
#include "mozilla/Likely.h"
#include "mozilla/LinkedList.h"
#include "nsAbsoluteContainingBlock.h"
#include "nsCRT.h"
#include "nsIAtom.h"
@ -1415,6 +1415,7 @@ nsCSSFrameConstructor::nsCSSFrameConstructor(nsIDocument *aDocument,
, mDocElementContainingBlock(nullptr)
, mGfxScrollFrame(nullptr)
, mPageSequenceFrame(nullptr)
, mCurrentDepth(0)
, mUpdateCount(0)
, mQuotesDirty(false)
, mCountersDirty(false)
@ -9841,6 +9842,12 @@ nsCSSFrameConstructor::ProcessChildren(nsFrameConstructorState& aState,
NS_PRECONDITION(aFrame->GetContentInsertionFrame() == aFrame,
"Parent frame in ProcessChildren should be its own "
"content insertion frame");
const uint32_t kMaxDepth = 2 * MAX_REFLOW_DEPTH;
MOZ_STATIC_ASSERT(kMaxDepth <= UINT16_MAX, "mCurrentDepth type is too narrow");
AutoRestore<uint16_t> savedDepth(mCurrentDepth);
if (mCurrentDepth != UINT16_MAX) {
++mCurrentDepth;
}
if (!aPossiblyLeafFrame) {
aPossiblyLeafFrame = aFrame;
@ -9938,6 +9945,11 @@ nsCSSFrameConstructor::ProcessChildren(nsFrameConstructorState& aState,
itemsToConstruct);
}
const bool addChildItems = MOZ_LIKELY(mCurrentDepth < kMaxDepth);
if (!addChildItems) {
NS_WARNING("ProcessChildren max depth exceeded");
}
ChildIterator iter, last;
for (ChildIterator::Init(aContent, &iter, &last);
iter != last;
@ -9948,8 +9960,12 @@ nsCSSFrameConstructor::ProcessChildren(nsFrameConstructorState& aState,
if (child->IsElement()) {
child->UnsetFlags(ELEMENT_ALL_RESTYLE_FLAGS);
}
AddFrameConstructionItems(aState, child, iter.XBLInvolved(), aFrame,
itemsToConstruct);
if (addChildItems) {
AddFrameConstructionItems(aState, child, iter.XBLInvolved(), aFrame,
itemsToConstruct);
} else {
ClearLazyBits(child, child->GetNextSibling());
}
}
itemsToConstruct.SetParentHasNoXBLChildren(!iter.XBLInvolved());

View File

@ -1878,6 +1878,8 @@ private:
nsIFrame* mPageSequenceFrame;
nsQuoteList mQuoteList;
nsCounterManager mCounterManager;
// Current ProcessChildren depth.
uint16_t mCurrentDepth;
uint16_t mUpdateCount;
bool mQuotesDirty : 1;
bool mCountersDirty : 1;