diff --git a/layout/svg/crashtests/873806-1.svg b/layout/svg/crashtests/873806-1.svg new file mode 100644 index 00000000000..e40aff201b7 --- /dev/null +++ b/layout/svg/crashtests/873806-1.svg @@ -0,0 +1,10 @@ + + + + a + + + + diff --git a/layout/svg/crashtests/crashtests.list b/layout/svg/crashtests/crashtests.list index e6cd2d856d3..82cf4d67764 100644 --- a/layout/svg/crashtests/crashtests.list +++ b/layout/svg/crashtests/crashtests.list @@ -163,4 +163,5 @@ load 849688-1.svg load 849688-2.svg load 860378-1.svg load 868904-1.svg +load 873806-1.svg load 877029-1.svg diff --git a/layout/svg/nsSVGOuterSVGFrame.cpp b/layout/svg/nsSVGOuterSVGFrame.cpp index 3b2e4cda4bf..3b8121539b1 100644 --- a/layout/svg/nsSVGOuterSVGFrame.cpp +++ b/layout/svg/nsSVGOuterSVGFrame.cpp @@ -167,6 +167,19 @@ nsSVGOuterSVGFrame::Init(nsIContent* aContent, SVGSVGElement *svg = static_cast(aContent); if (!svg->PassesConditionalProcessingTests()) { AddStateBits(NS_STATE_SVG_NONDISPLAY_CHILD); + } else { + // If this outer element is the child of a that + // is non-display, or is the child of a frame for HTML content that + // itself is a descendant of a non-display SVG frame, then we want to + // it non-display also. The second case is not as simple to handle + // as copying a state bit from the parent, since non-SVG frames do + // not use NS_STATE_SVG_NONDISPLAY_CHILD. + for (nsIFrame* f = aParent; f; f = f->GetParent()) { + if (f->IsFrameOfType(eSVG)) { + AddStateBits(f->GetStateBits() & NS_STATE_SVG_NONDISPLAY_CHILD); + break; + } + } } nsSVGOuterSVGFrameBase::Init(aContent, aParent, aPrevInFlow); diff --git a/layout/svg/nsSVGTextFrame2.cpp b/layout/svg/nsSVGTextFrame2.cpp index cf5db68a20f..c7dbd8f6be7 100644 --- a/layout/svg/nsSVGTextFrame2.cpp +++ b/layout/svg/nsSVGTextFrame2.cpp @@ -3074,6 +3074,9 @@ nsSVGTextFrame2::DidSetStyleContext(nsStyleContext* aOldStyleContext) void nsSVGTextFrame2::ReflowSVGNonDisplayText() { + MOZ_ASSERT(nsSVGUtils::AnyOuterSVGIsCallingReflowSVG(this), + "only call ReflowSVGNonDisplayText when an outer SVG frame is " + "under ReflowSVG"); MOZ_ASSERT(mState & NS_STATE_SVG_NONDISPLAY_CHILD, "only call ReflowSVGNonDisplayText if the frame is " "NS_STATE_SVG_NONDISPLAY_CHILD"); @@ -4832,6 +4835,8 @@ nsSVGTextFrame2::UpdateGlyphPositioning() // by nsSVGDisplayContainerFrame::ReflowSVG.) kid->AddStateBits(NS_FRAME_IS_DIRTY); } + MOZ_ASSERT(nsSVGUtils::AnyOuterSVGIsCallingReflowSVG(this), + "should be under ReflowSVG"); nsPresContext::InterruptPreventer noInterrupts(PresContext()); DoReflow(); } diff --git a/layout/svg/nsSVGUtils.cpp b/layout/svg/nsSVGUtils.cpp index 5d24ff7bc8f..58b0e1a7d80 100644 --- a/layout/svg/nsSVGUtils.cpp +++ b/layout/svg/nsSVGUtils.cpp @@ -451,6 +451,19 @@ nsSVGUtils::OuterSVGIsCallingReflowSVG(nsIFrame *aFrame) return GetOuterSVGFrame(aFrame)->IsCallingReflowSVG(); } +bool +nsSVGUtils::AnyOuterSVGIsCallingReflowSVG(nsIFrame* aFrame) +{ + nsSVGOuterSVGFrame* outer = GetOuterSVGFrame(aFrame); + do { + if (outer->IsCallingReflowSVG()) { + return true; + } + outer = GetOuterSVGFrame(outer->GetParent()); + } while (outer); + return false; +} + void nsSVGUtils::ScheduleReflowSVG(nsIFrame *aFrame) { diff --git a/layout/svg/nsSVGUtils.h b/layout/svg/nsSVGUtils.h index 5c0243ab759..41f3ea62687 100644 --- a/layout/svg/nsSVGUtils.h +++ b/layout/svg/nsSVGUtils.h @@ -521,6 +521,7 @@ public: static nsIFrame* GetFirstNonAAncestorFrame(nsIFrame* aStartFrame); static bool OuterSVGIsCallingReflowSVG(nsIFrame *aFrame); + static bool AnyOuterSVGIsCallingReflowSVG(nsIFrame *aFrame); /* * Get any additional transforms that apply only to stroking