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 @@
+
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