Fix crash when recreating <caption> frames. Add ASSERTIONs to detect similar frame construction errors in the future. b=341382 r+sr=bzbarsky

This commit is contained in:
mats.palmgren%bredband.net 2006-06-29 02:32:36 +00:00
Родитель b6c492a688
Коммит 153ab238ca
14 изменённых файлов: 149 добавлений и 36 удалений

Просмотреть файл

@ -9636,11 +9636,17 @@ nsCSSFrameConstructor::ContentInserted(nsIContent* aContainer,
if (NS_SUCCEEDED(rv) && newCaptionFrame) {
nsIFrame* outerTableFrame;
if (GetCaptionAdjustedParent(parentFrame, newCaptionFrame, &outerTableFrame)) {
// If we did adjust the parent then the calculated insertion point is
// now invalid (bug 341382).
if (parentFrame != outerTableFrame) {
prevSibling = nsnull;
}
// If the parent is not a outer table frame we will try to add frames
// to a named child list that the parent does not honour and the frames
// will get lost
NS_ASSERTION(nsLayoutAtoms::tableOuterFrame == outerTableFrame->GetType(),
"Pseudo frame construction failure, a caption can be only a child of a outer table frame");
"Pseudo frame construction failure, "
"a caption can be only a child of a outer table frame");
if (isAppend) {
state.mFrameManager->AppendFrames(outerTableFrame,
nsLayoutAtoms::captionList,

Просмотреть файл

@ -625,6 +625,10 @@ nsFieldSetFrame::InsertFrames(nsIAtom* aListName,
nsIFrame* aPrevFrame,
nsIFrame* aFrameList)
{
NS_ASSERTION(!aPrevFrame || aPrevFrame->GetParent() == this ||
aPrevFrame->GetParent() == mContentFrame,
"inserting after sibling frame with different parent");
aFrameList = MaybeSetLegend(aFrameList, aListName);
if (aFrameList) {
ReParentFrameList(aFrameList);

Просмотреть файл

@ -83,6 +83,8 @@ nsAbsoluteContainingBlock::AppendFrames(nsIFrame* aDelegatingFrame,
nsIAtom* aListName,
nsIFrame* aFrameList)
{
NS_ASSERTION(GetChildListName() == aListName, "unexpected child list");
// Append the frames to our list of absolutely positioned frames
#ifdef NS_DEBUG
nsFrame::VerifyDirtyBitSet(aFrameList);
@ -101,7 +103,10 @@ nsAbsoluteContainingBlock::InsertFrames(nsIFrame* aDelegatingFrame,
nsIFrame* aPrevFrame,
nsIFrame* aFrameList)
{
// Insert the new frames
NS_ASSERTION(GetChildListName() == aListName, "unexpected child list");
NS_ASSERTION(!aPrevFrame || aPrevFrame->GetParent() == aDelegatingFrame,
"inserting after sibling frame with different parent");
#ifdef NS_DEBUG
nsFrame::VerifyDirtyBitSet(aFrameList);
#endif
@ -118,6 +123,8 @@ nsAbsoluteContainingBlock::RemoveFrame(nsIFrame* aDelegatingFrame,
nsIAtom* aListName,
nsIFrame* aOldFrame)
{
NS_ASSERTION(GetChildListName() == aListName, "unexpected child list");
PRBool result = mAbsoluteFrames.DestroyFrame(aOldFrame);
NS_ASSERTION(result, "didn't find frame to delete");
// Because positioned frames aren't part of a flow, there's no additional

Просмотреть файл

@ -5347,15 +5347,18 @@ nsBlockFrame::AppendFrames(nsIAtom* aListName,
if (nsnull == aFrameList) {
return NS_OK;
}
if (mAbsoluteContainer.GetChildListName() == aListName) {
return mAbsoluteContainer.AppendFrames(this, aListName, aFrameList);
}
else if (nsLayoutAtoms::floatList == aListName) {
mFloats.AppendFrames(nsnull, aFrameList);
return NS_OK;
}
else if (nsnull != aListName) {
return NS_ERROR_INVALID_ARG;
if (aListName) {
if (mAbsoluteContainer.GetChildListName() == aListName) {
return mAbsoluteContainer.AppendFrames(this, aListName, aFrameList);
}
else if (nsLayoutAtoms::floatList == aListName) {
mFloats.AppendFrames(nsnull, aFrameList);
return NS_OK;
}
else {
NS_ERROR("unexpected child list");
return NS_ERROR_INVALID_ARG;
}
}
// Find the proper last-child for where the append should go
@ -5389,19 +5392,25 @@ nsBlockFrame::InsertFrames(nsIAtom* aListName,
nsIFrame* aPrevFrame,
nsIFrame* aFrameList)
{
if (mAbsoluteContainer.GetChildListName() == aListName) {
return mAbsoluteContainer.InsertFrames(this, aListName, aPrevFrame,
aFrameList);
}
else if (nsLayoutAtoms::floatList == aListName) {
mFloats.InsertFrames(this, aPrevFrame, aFrameList);
return NS_OK;
}
NS_ASSERTION(!aPrevFrame || aPrevFrame->GetParent() == this,
"inserting after sibling frame with different parent");
if (aListName) {
if (mAbsoluteContainer.GetChildListName() == aListName) {
return mAbsoluteContainer.InsertFrames(this, aListName, aPrevFrame,
aFrameList);
}
else if (nsLayoutAtoms::floatList == aListName) {
mFloats.InsertFrames(this, aPrevFrame, aFrameList);
return NS_OK;
}
#ifdef IBMBIDI
else if (nsLayoutAtoms::nextBidi == aListName) {}
else if (nsLayoutAtoms::nextBidi == aListName) {}
#endif // IBMBIDI
else if (nsnull != aListName) {
return NS_ERROR_INVALID_ARG;
else {
NS_ERROR("unexpected child list");
return NS_ERROR_INVALID_ARG;
}
}
#ifdef NOISY_REFLOW_REASON
@ -5678,6 +5687,7 @@ nsBlockFrame::RemoveFrame(nsIAtom* aListName,
}
#endif // IBMBIDI
else {
NS_ERROR("unexpected child list");
rv = NS_ERROR_INVALID_ARG;
}

Просмотреть файл

@ -165,18 +165,23 @@ nsFrameList::InsertFrame(nsIFrame* aParent,
{
NS_PRECONDITION(nsnull != aNewFrame, "null ptr");
if (nsnull != aNewFrame) {
if (aParent) {
aNewFrame->SetParent(aParent);
}
if (nsnull == aPrevSibling) {
aNewFrame->SetNextSibling(mFirstChild);
mFirstChild = aNewFrame;
}
else {
NS_ASSERTION(aNewFrame->GetParent() == aPrevSibling->GetParent(),
"prev sibling has different parent");
nsIFrame* nextFrame = aPrevSibling->GetNextSibling();
NS_ASSERTION(!nextFrame ||
aNewFrame->GetParent() == nextFrame->GetParent(),
"next sibling has different parent");
aPrevSibling->SetNextSibling(aNewFrame);
aNewFrame->SetNextSibling(nextFrame);
}
if (aParent) {
aNewFrame->SetParent(aParent);
}
}
#ifdef DEBUG
CheckForLoops();
@ -211,7 +216,12 @@ nsFrameList::InsertFrames(nsIFrame* aParent,
mFirstChild = aFrameList;
}
else {
NS_ASSERTION(aFrameList->GetParent() == aPrevSibling->GetParent(),
"prev sibling has different parent");
nsIFrame* nextFrame = aPrevSibling->GetNextSibling();
NS_ASSERTION(!nextFrame ||
aFrameList->GetParent() == nextFrame->GetParent(),
"next sibling has different parent");
aPrevSibling->SetNextSibling(aFrameList);
lastNewFrame->SetNextSibling(nextFrame);
}

Просмотреть файл

@ -201,6 +201,8 @@ nsHTMLScrollFrame::InsertFrames(nsIAtom* aListName,
nsIFrame* aFrameList)
{
NS_ASSERTION(!aListName, "Only main list supported");
NS_ASSERTION(!aPrevFrame || aPrevFrame->GetParent() == this,
"inserting after sibling frame with different parent");
mFrames.InsertFrames(nsnull, aPrevFrame, aFrameList);
mInner.ReloadChildFrames();
return NS_OK;

Просмотреть файл

@ -177,7 +177,10 @@ nsInlineFrame::AppendFrames(nsIAtom* aListName,
#ifdef IBMBIDI
if (aListName != nsLayoutAtoms::nextBidi)
#endif
{
NS_ERROR("unexpected child list");
return NS_ERROR_INVALID_ARG;
}
}
if (aFrameList) {
mFrames.AppendFrames(this, aFrameList);
@ -196,11 +199,17 @@ nsInlineFrame::InsertFrames(nsIAtom* aListName,
nsIFrame* aPrevFrame,
nsIFrame* aFrameList)
{
NS_ASSERTION(!aPrevFrame || aPrevFrame->GetParent() == this,
"inserting after sibling frame with different parent");
if (nsnull != aListName) {
#ifdef IBMBIDI
if (aListName != nsLayoutAtoms::nextBidi)
#endif
return NS_ERROR_INVALID_ARG;
{
NS_ERROR("unexpected child list");
return NS_ERROR_INVALID_ARG;
}
}
if (aFrameList) {
// Insert frames after aPrevFrame
@ -223,7 +232,10 @@ nsInlineFrame::RemoveFrame(nsIAtom* aListName,
#ifdef IBMBIDI
if (nsLayoutAtoms::nextBidi != aListName)
#endif
return NS_ERROR_INVALID_ARG;
{
NS_ERROR("unexpected child list");
return NS_ERROR_INVALID_ARG;
}
}
if (aOldFrame) {

Просмотреть файл

@ -71,6 +71,10 @@ nsSVGContainerFrame::InsertFrames(nsIAtom* aListName,
nsIFrame* aPrevFrame,
nsIFrame* aFrameList)
{
NS_ASSERTION(!aListName, "unexpected child list");
NS_ASSERTION(!aPrevFrame || aPrevFrame->GetParent() == this,
"inserting after sibling frame with different parent");
mFrames.InsertFrames(this, aPrevFrame, aFrameList);
return NS_OK;
@ -80,7 +84,9 @@ NS_IMETHODIMP
nsSVGContainerFrame::RemoveFrame(nsIAtom* aListName,
nsIFrame* aOldFrame)
{
return mFrames.DestroyFrame(aOldFrame);
NS_ASSERTION(!aListName, "unexpected child list");
return mFrames.DestroyFrame(aOldFrame) ? NS_OK : NS_ERROR_FAILURE;
}
NS_IMETHODIMP

Просмотреть файл

@ -211,6 +211,8 @@ NS_IMETHODIMP
nsTableColGroupFrame::AppendFrames(nsIAtom* aListName,
nsIFrame* aFrameList)
{
NS_ASSERTION(!aListName, "unexpected child list");
nsTableColFrame* col = GetFirstColumn();
nsTableColFrame* nextCol;
while (col && col->GetColType() == eColAnonymousColGroup) {
@ -228,9 +230,13 @@ nsTableColGroupFrame::AppendFrames(nsIAtom* aListName,
NS_IMETHODIMP
nsTableColGroupFrame::InsertFrames(nsIAtom* aListName,
nsIFrame* aPrevFrameIn,
nsIFrame* aPrevFrame,
nsIFrame* aFrameList)
{
NS_ASSERTION(!aListName, "unexpected child list");
NS_ASSERTION(!aPrevFrame || aPrevFrame->GetParent() == this,
"inserting after sibling frame with different parent");
nsFrameList frames(aFrameList); // convience for getting last frame
nsIFrame* lastFrame = frames.LastChild();
@ -244,8 +250,8 @@ nsTableColGroupFrame::InsertFrames(nsIAtom* aListName,
col = nextCol;
}
mFrames.InsertFrames(this, aPrevFrameIn, aFrameList);
nsIFrame* prevFrame = nsTableFrame::GetFrameAtOrBefore(this, aPrevFrameIn,
mFrames.InsertFrames(this, aPrevFrame, aFrameList);
nsIFrame* prevFrame = nsTableFrame::GetFrameAtOrBefore(this, aPrevFrame,
nsLayoutAtoms::tableColFrame);
PRInt32 colIndex = (prevFrame) ? ((nsTableColFrame*)prevFrame)->GetColIndex() + 1 : GetStartColumnIndex();
@ -309,6 +315,8 @@ NS_IMETHODIMP
nsTableColGroupFrame::RemoveFrame(nsIAtom* aListName,
nsIFrame* aOldFrame)
{
NS_ASSERTION(!aListName, "unexpected child list");
if (!aOldFrame) return NS_OK;
if (nsLayoutAtoms::tableColFrame == aOldFrame->GetType()) {

Просмотреть файл

@ -383,7 +383,7 @@ nsTableFrame::PageBreakAfter(nsIFrame& aSourceFrame,
}
// XXX this needs to be cleaned up so that the frame constructor breaks out col group
// frames into a separate child list.
// frames into a separate child list, bug 343048.
NS_IMETHODIMP
nsTableFrame::SetInitialChildList(nsIAtom* aListName,
nsIFrame* aChildList)
@ -2433,8 +2433,13 @@ NS_IMETHODIMP
nsTableFrame::AppendFrames(nsIAtom* aListName,
nsIFrame* aFrameList)
{
NS_ASSERTION(!aListName || aListName == nsLayoutAtoms::colGroupList,
"unexpected child list");
// Because we actually have two child lists, one for col group frames and one
// for everything else, we need to look at each frame individually
// XXX The frame construction code should be separating out child frames
// based on the type, bug 343048.
nsIFrame* f = aFrameList;
while (f) {
// Get the next frame and disconnect this frame from its sibling
@ -2493,13 +2498,17 @@ nsTableFrame::InsertFrames(nsIAtom* aListName,
// row group frames and col group frames go in separate child lists and
// so if there's more than one this gets messy...
// XXX The frame construction code should be separating out child frames
// based on the type...
// based on the type, bug 343048.
NS_PRECONDITION(!aFrameList->GetNextSibling(), "expected only one child frame");
NS_ASSERTION(!aPrevFrame || aPrevFrame->GetParent() == this,
"inserting after sibling frame with different parent");
// See what kind of frame we have
const nsStyleDisplay* display = aFrameList->GetStyleDisplay();
if (NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP == display->mDisplay) {
NS_ASSERTION(!aListName || aListName == nsLayoutAtoms::colGroupList,
"unexpected child list");
// Insert the column group frame
nsFrameList frames(aFrameList); // convience for getting last frame
nsIFrame* lastFrame = frames.LastChild();
@ -2517,6 +2526,7 @@ nsTableFrame::InsertFrames(nsIAtom* aListName,
InsertColGroups(startColIndex, aFrameList, lastFrame);
SetNeedStrategyInit(PR_TRUE);
} else if (IsRowGroup(display->mDisplay)) {
NS_ASSERTION(!aListName, "unexpected child list");
nsFrameList newList(aFrameList);
nsIFrame* lastSibling = newList.LastChild();
// Insert the frames in the sibling chain
@ -2525,6 +2535,7 @@ nsTableFrame::InsertFrames(nsIAtom* aListName,
InsertRowGroups(aFrameList, lastSibling);
SetNeedStrategyInit(PR_TRUE);
} else {
NS_ASSERTION(!aListName, "unexpected child list");
// Just insert the frame and don't worry about reflowing it
mFrames.InsertFrame(nsnull, aPrevFrame, aFrameList);
return NS_OK;
@ -2545,7 +2556,11 @@ nsTableFrame::RemoveFrame(nsIAtom* aListName,
// See what kind of frame we have
const nsStyleDisplay* display = aOldFrame->GetStyleDisplay();
// XXX The frame construction code should be separating out child frames
// based on the type, bug 343048.
if (NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP == display->mDisplay) {
NS_ASSERTION(!aListName || aListName == nsLayoutAtoms::colGroupList,
"unexpected child list");
nsIFrame* nextColGroupFrame = aOldFrame->GetNextSibling();
nsTableColGroupFrame* colGroup = (nsTableColGroupFrame*)aOldFrame;
PRInt32 firstColIndex = colGroup->GetStartColumnIndex();
@ -2572,6 +2587,7 @@ nsTableFrame::RemoveFrame(nsIAtom* aListName,
SetNeedStrategyInit(PR_TRUE);
AppendDirtyReflowCommand(this);
} else {
NS_ASSERTION(!aListName, "unexpected child list");
nsTableRowGroupFrame* rgFrame = GetRowGroupFrame(aOldFrame);
if (rgFrame) {
PRInt32 startRowIndex = rgFrame->GetStartRowIndex();
@ -2606,7 +2622,6 @@ nsTableFrame::RemoveFrame(nsIAtom* aListName,
} else {
// Just remove the frame
mFrames.DestroyFrame(aOldFrame);
return NS_OK;
}
}
#ifdef DEBUG_TABLE_CELLMAP

Просмотреть файл

@ -199,6 +199,10 @@ nsTableOuterFrame::SetInitialChildList(nsIAtom* aListName,
if (nsLayoutAtoms::tableFrame == aChildList->GetType()) {
mInnerTableFrame = (nsTableFrame*)aChildList;
}
else {
NS_ERROR("expected a table frame");
return NS_ERROR_INVALID_ARG;
}
}
}
@ -214,6 +218,9 @@ nsTableOuterFrame::AppendFrames(nsIAtom* aListName,
// We only have two child frames: the inner table and a caption frame.
// The inner frame is provided when we're initialized, and it cannot change
if (nsLayoutAtoms::captionList == aListName) {
NS_ASSERTION(!aFrameList ||
aFrameList->GetType() == nsLayoutAtoms::tableCaptionFrame,
"appending non-caption frame to captionList");
mCaptionFrames.AppendFrames(this, aFrameList);
mCaptionFrame = mCaptionFrames.FirstChild();
@ -225,7 +232,7 @@ nsTableOuterFrame::AppendFrames(nsIAtom* aListName,
}
else {
NS_PRECONDITION(PR_FALSE, "unexpected child frame type");
NS_PRECONDITION(PR_FALSE, "unexpected child list");
rv = NS_ERROR_UNEXPECTED;
}
@ -238,6 +245,11 @@ nsTableOuterFrame::InsertFrames(nsIAtom* aListName,
nsIFrame* aFrameList)
{
if (nsLayoutAtoms::captionList == aListName) {
NS_ASSERTION(!aPrevFrame || aPrevFrame->GetParent() == this,
"inserting after sibling frame with different parent");
NS_ASSERTION(!aFrameList ||
aFrameList->GetType() == nsLayoutAtoms::tableCaptionFrame,
"inserting non-caption frame into captionList");
mCaptionFrames.InsertFrames(nsnull, aPrevFrame, aFrameList);
mCaptionFrame = mCaptionFrames.FirstChild();
return NS_OK;

Просмотреть файл

@ -210,6 +210,8 @@ NS_IMETHODIMP
nsTableRowFrame::AppendFrames(nsIAtom* aListName,
nsIFrame* aFrameList)
{
NS_ASSERTION(!aListName, "unexpected child list");
// Append the frames
mFrames.AppendFrames(nsnull, aFrameList);
@ -238,6 +240,10 @@ nsTableRowFrame::InsertFrames(nsIAtom* aListName,
nsIFrame* aPrevFrame,
nsIFrame* aFrameList)
{
NS_ASSERTION(!aListName, "unexpected child list");
NS_ASSERTION(!aPrevFrame || aPrevFrame->GetParent() == this,
"inserting after sibling frame with different parent");
// Get the table frame
nsTableFrame* tableFrame = nsTableFrame::GetTableFrame(this);
@ -274,7 +280,8 @@ NS_IMETHODIMP
nsTableRowFrame::RemoveFrame(nsIAtom* aListName,
nsIFrame* aOldFrame)
{
// Get the table frame
NS_ASSERTION(!aListName, "unexpected child list");
nsTableFrame* tableFrame = nsTableFrame::GetTableFrame(this);
if (tableFrame) {
if (IS_TABLE_CELL(aOldFrame->GetType())) {
@ -296,6 +303,10 @@ nsTableRowFrame::RemoveFrame(nsIAtom* aListName,
// in case another cell gets added to the row during a reflow coallesce.
tableFrame->AppendDirtyReflowCommand(this);
}
else {
NS_ERROR("unexpected frame type");
return NS_ERROR_INVALID_ARG;
}
}
return NS_OK;

Просмотреть файл

@ -1351,6 +1351,8 @@ NS_IMETHODIMP
nsTableRowGroupFrame::AppendFrames(nsIAtom* aListName,
nsIFrame* aFrameList)
{
NS_ASSERTION(!aListName, "unexpected child list");
// collect the new row frames in an array
nsAutoVoidArray rows;
for (nsIFrame* rowFrame = aFrameList; rowFrame;
@ -1395,6 +1397,10 @@ nsTableRowGroupFrame::InsertFrames(nsIAtom* aListName,
nsIFrame* aPrevFrame,
nsIFrame* aFrameList)
{
NS_ASSERTION(!aListName, "unexpected child list");
NS_ASSERTION(!aPrevFrame || aPrevFrame->GetParent() == this,
"inserting after sibling frame with different parent");
nsTableFrame* tableFrame = nsTableFrame::GetTableFrame(this);
if (!tableFrame)
return NS_ERROR_NULL_POINTER;
@ -1449,6 +1455,8 @@ NS_IMETHODIMP
nsTableRowGroupFrame::RemoveFrame(nsIAtom* aListName,
nsIFrame* aOldFrame)
{
NS_ASSERTION(!aListName, "unexpected child list");
nsTableFrame* tableFrame = nsTableFrame::GetTableFrame(this);
if (tableFrame) {
if (nsLayoutAtoms::tableRowFrame == aOldFrame->GetType()) {

Просмотреть файл

@ -1158,6 +1158,8 @@ nsBoxFrame::InsertFrames(nsIAtom* aListName,
nsIFrame* aPrevFrame,
nsIFrame* aFrameList)
{
NS_ASSERTION(!aPrevFrame || aPrevFrame->GetParent() == this,
"inserting after sibling frame with different parent");
NS_PRECONDITION(!aListName, "We don't support out-of-flow kids");
nsBoxLayoutState state(GetPresContext());