Bug 794693, part 2: Perform parent reflow state calculation at the box-block interface before setting up child reflow state to prevent crashing when a parent reflow state is assumed to be non-null. [r=dbaron]
☠☠ backed out by 29bbbd1de60b ☠ ☠
authorScott Johnson <sjohnson@mozilla.com>
Sat, 07 Sep 2013 19:02:11 -0500
changeset 146070 8f09d30d35715b349d783b715ddae25e17e15b41
parent 146069 dfe69eabbe477ee77e481833995862370a180f74
child 146071 61a6c74ce93eddbb99f06bd6d4b7de54891055ba
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewersdbaron
bugs794693
milestone26.0a1
Bug 794693, part 2: Perform parent reflow state calculation at the box-block interface before setting up child reflow state to prevent crashing when a parent reflow state is assumed to be non-null. [r=dbaron]
layout/generic/crashtests/794693.html
layout/generic/crashtests/crashtests.list
layout/generic/nsFrame.cpp
layout/generic/nsHTMLReflowState.cpp
new file mode 100644
--- /dev/null
+++ b/layout/generic/crashtests/794693.html
@@ -0,0 +1,9 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <body style="display: -moz-box;">
+    <font style="display: table; float: left;">
+      <span style="display: table;">
+        text text
+      </span>
+    </font>
+  </body>
+</html>
--- a/layout/generic/crashtests/crashtests.list
+++ b/layout/generic/crashtests/crashtests.list
@@ -461,16 +461,17 @@ load 762764-1.html
 load 765409.html
 asserts(0-200) load 765621.html # bug 703550
 asserts(0-200) load 767765.html # bug 407550, bug 871758, and various nscoord_MAX related asserts
 load 769303-1.html
 load 769303-2.html
 load 769120.html
 load 786740-1.html
 asserts(0-4) test-pref(font.size.inflation.emPerLine,15) load 791601.xhtml # 3 counts of bug 871327, 1 bug 367185
+pref(font.size.inflation.minTwips,120) load 794693.html
 asserts(8) test-pref(layout.css.flexbox.enabled,true) load 798020-1.html
 test-pref(layout.css.flexbox.enabled,true) load 798235-1.html
 test-pref(layout.css.flexbox.enabled,true) load 799207-1.html
 asserts(12) test-pref(layout.css.flexbox.enabled,true) load 799207-2.html
 test-pref(layout.css.flexbox.enabled,true) load 801268-1.html
 test-pref(layout.css.flexbox.enabled,true) load 804089-1.xhtml
 load 810726.html
 test-pref(layout.css.flexbox.enabled,true) load 825810-1.html
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -7765,25 +7765,16 @@ nsFrame::BoxReflow(nsBoxLayoutState&    
 #ifdef DEBUG_REFLOW
   nsAdaptorAddIndents();
   printf("Reflowing: ");
   nsFrame::ListTag(stdout, mFrame);
   printf("\n");
   gIndent2++;
 #endif
 
-  //printf("width=%d, height=%d\n", aWidth, aHeight);
-  /*
-  nsIFrame* parent;
-  GetParentBox(&parent);
-
- // if (parent->GetStateBits() & NS_STATE_CURRENTLY_IN_DEBUG)
-  //   printf("In debug\n");
-  */
-
   nsBoxLayoutMetrics *metrics = BoxMetrics();
   nsReflowStatus status = NS_FRAME_COMPLETE;
 
   bool needsReflow = NS_SUBTREE_DIRTY(this);
 
   // if we don't need a reflow then 
   // lets see if we are already that size. Yes? then don't even reflow. We are done.
   if (!needsReflow) {
@@ -7850,40 +7841,45 @@ nsFrame::BoxReflow(nsBoxLayoutState&    
       parentReflowState.SetComputedHeight(std::max(parentSize.height, 0));
     parentReflowState.mComputedMargin.SizeTo(0, 0, 0, 0);
     // XXX use box methods
     parentFrame->GetPadding(parentReflowState.mComputedPadding);
     parentFrame->GetBorder(parentReflowState.mComputedBorderPadding);
     parentReflowState.mComputedBorderPadding +=
       parentReflowState.mComputedPadding;
 
-    // XXX Is it OK that this reflow state has no parent reflow state?
-    // (It used to have a bogus parent, skipping all the boxes).
-    nsSize availSize(aWidth, NS_INTRINSICSIZE);
-    nsHTMLReflowState reflowState(aPresContext, this, aRenderingContext,
-                                  availSize,
-                                  nsHTMLReflowState::DUMMY_PARENT_REFLOW_STATE);
-
     // Construct the parent chain manually since constructing it normally
     // messes up dimensions.
     const nsHTMLReflowState *outerReflowState = aState.OuterReflowState();
     NS_ASSERTION(!outerReflowState || outerReflowState->frame != this,
                  "in and out of XUL on a single frame?");
+    const nsHTMLReflowState* parentRS;
     if (outerReflowState && outerReflowState->frame == parentFrame) {
       // We're a frame (such as a text control frame) that jumps into
       // box reflow and then straight out of it on the child frame.
       // This means we actually have a real parent reflow state.
       // nsLayoutUtils::InflationMinFontSizeFor used to need this to be
       // linked up correctly for text control frames, so do so here).
-      reflowState.parentReflowState = outerReflowState;
-      reflowState.mCBReflowState = outerReflowState;
+      parentRS = outerReflowState;
     } else {
-      reflowState.parentReflowState = &parentReflowState;
-      reflowState.mCBReflowState = &parentReflowState;
-    }
+      parentRS = &parentReflowState;
+    }
+
+    // XXX Is it OK that this reflow state has only one ancestor?
+    // (It used to have a bogus parent, skipping all the boxes).
+    nsSize availSize(aWidth, NS_INTRINSICSIZE);
+    nsHTMLReflowState reflowState(aPresContext, *parentRS, this,
+                                  availSize, -1, -1,
+                                  nsHTMLReflowState::DUMMY_PARENT_REFLOW_STATE);
+
+    // XXX_jwir3: This is somewhat fishy. If this is actually changing the value
+    //            here (which it might be), then we should make sure that it's
+    //            correct the first time around, rather than changing it later.
+    reflowState.mCBReflowState = parentRS;
+
     reflowState.mReflowDepth = aState.GetReflowDepth();
 
     // mComputedWidth and mComputedHeight are content-box, not
     // border-box
     if (aWidth != NS_INTRINSICSIZE) {
       nscoord computedWidth =
         aWidth - reflowState.mComputedBorderPadding.LeftRight();
       computedWidth = std::max(computedWidth, 0);
--- a/layout/generic/nsHTMLReflowState.cpp
+++ b/layout/generic/nsHTMLReflowState.cpp
@@ -1840,17 +1840,17 @@ nsHTMLReflowState::InitConstraints(nsPre
                                    nsIAtom* aFrameType)
 {
   DISPLAY_INIT_CONSTRAINTS(frame, this,
                            aContainingBlockWidth, aContainingBlockHeight,
                            aBorder, aPadding);
 
   // If this is a reflow root, then set the computed width and
   // height equal to the available space
-  if (nullptr == parentReflowState) {
+  if (nullptr == parentReflowState || mFlags.mDummyParentReflowState) {
     // XXXldb This doesn't mean what it used to!
     InitOffsets(aContainingBlockWidth,
                 VerticalOffsetPercentBasis(frame, aContainingBlockWidth,
                                            aContainingBlockHeight),
                 aFrameType, aBorder, aPadding);
     // Override mComputedMargin since reflow roots start from the
     // frame's boundary, which is inside the margin.
     mComputedMargin.SizeTo(0, 0, 0, 0);