Bug 1437155: Avoid giving a first-letter frame to a display: contents element. r=mats

It doesn't make sense, since they have no frame themselves, and it breaks
invariants other code relies on. Use the parent frame instead.

The stack overflow happens because we give the first-letter frame to the
display: contents element, then we reframe it.

Removing a display: contents node calls ContentRemoved on all the children. One
of these children is this text-node inside the first-letter frame. Since it was
split by bidi resolution we go ahead and reframe the parent in:

  https://searchfox.org/mozilla-central/rev/d2b4b40901c15614fad2fa34718eea428774306e/layout/base/nsCSSFrameConstructor.cpp#9688

But the parent is the display: contents node, which results in infinite
recursion.

The usage of GetParent() is wrong anyway too, since it doesn't handle XBL or
Shadow DOM in any way.

MozReview-Commit-ID: JFD16at316V
This commit is contained in:
Emilio Cobos Álvarez
2018-03-05 11:42:12 +01:00
parent b7779e5335
commit c67cd5178d
3 changed files with 18 additions and 5 deletions

View File

@@ -11436,9 +11436,8 @@ nsCSSFrameConstructor::CreateFloatingLetterFrame(
nsFirstLetterFrame* letterFrame =
NS_NewFirstLetterFrame(mPresShell, aStyleContext);
// We don't want to use a text content for a non-text frame (because we want
// its primary frame to be a text frame). So use its parent for the
// first-letter.
nsIContent* letterContent = aTextContent->GetParent();
// its primary frame to be a text frame).
nsIContent* letterContent = aParentFrame->GetContent();
nsContainerFrame* containingBlock = aState.GetGeometricParent(
aStyleContext->StyleDisplay(), aParentFrame);
InitAndRestoreFrame(aState, letterContent, containingBlock, letterFrame);
@@ -11573,8 +11572,8 @@ nsCSSFrameConstructor::CreateLetterFrame(nsContainerFrame* aBlockFrame,
// Initialize the first-letter-frame. We don't want to use a text
// content for a non-text frame (because we want its primary frame to
// be a text frame). So use its parent for the first-letter.
nsIContent* letterContent = aTextContent->GetParent();
// be a text frame).
nsIContent* letterContent = aParentFrame->GetContent();
letterFrame->Init(letterContent, aParentFrame, nullptr);
InitAndRestoreFrame(state, aTextContent, letterFrame, textFrame);