Title: [144744] trunk
- Revision
- 144744
- Author
- [email protected]
- Date
- 2013-03-05 02:27:35 -0800 (Tue, 05 Mar 2013)
Log Message
[CSS Regions] Crash when MathML used in CSS Regions
https://bugs.webkit.org/show_bug.cgi?id=110686
Reviewed by David Hyatt.
Source/WebCore:
The MathML blocks trigger a children layout when computing the preferred widths. This happens to determine the preferred
logical heights of the children. When the layout reaches the line boxes computation the preferred width of the containing block
is requested. Because it wasn't computed, the layout of the children is started again to determine the preferred logical heights.
This causes an infinite recursion and triggers a stack overflow.
The patch introduces a new RAII utility class that disables fragmentation when the constructor is called and restores it
on the destructor. This class is used when computing the preferred height for the children of a MathML block.
Test: fast/regions/mathml-crash.html
* rendering/RenderObject.cpp:
(WebCore::RenderObject::setFlowThreadStateIncludingDescendants): Do not cross RenderFlowThread boundaries when updating the flow thread
state flag. The innermost flow threads need to manage their descendants flag values.
* rendering/RenderView.cpp:
(WebCore::FragmentationDisabler::FragmentationDisabler):
(WebCore):
(WebCore::FragmentationDisabler::~FragmentationDisabler):
* rendering/RenderView.h:
(FragmentationDisabler):
(WebCore):
* rendering/mathml/RenderMathMLBlock.cpp:
(WebCore::RenderMathMLBlock::computeChildrenPreferredLogicalHeights):
LayoutTests:
Add a test to verify regions and MathML do not crash.
* fast/regions/mathml-crash-expected.txt: Added.
* fast/regions/mathml-crash.html: Added.
Modified Paths
Added Paths
Diff
Modified: trunk/LayoutTests/ChangeLog (144743 => 144744)
--- trunk/LayoutTests/ChangeLog 2013-03-05 10:05:41 UTC (rev 144743)
+++ trunk/LayoutTests/ChangeLog 2013-03-05 10:27:35 UTC (rev 144744)
@@ -1,3 +1,15 @@
+2013-03-05 Andrei Bucur <[email protected]>
+
+ [CSS Regions] Crash when MathML used in CSS Regions
+ https://bugs.webkit.org/show_bug.cgi?id=110686
+
+ Reviewed by David Hyatt.
+
+ Add a test to verify regions and MathML do not crash.
+
+ * fast/regions/mathml-crash-expected.txt: Added.
+ * fast/regions/mathml-crash.html: Added.
+
2013-03-05 Sudarsana Nagineni <[email protected]>
Unreviewed, EFL gardening.
Added: trunk/LayoutTests/fast/regions/mathml-crash-expected.txt (0 => 144744)
--- trunk/LayoutTests/fast/regions/mathml-crash-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/regions/mathml-crash-expected.txt 2013-03-05 10:27:35 UTC (rev 144744)
@@ -0,0 +1,8 @@
+PASS successfullyParsed is true
+
+TEST COMPLETE
+Bug 110686: [CSS Regions] Crash when MathML used in CSS Regions
+
+This test PASSES if it does not CRASH or ASSERT.
+
+
Added: trunk/LayoutTests/fast/regions/mathml-crash.html (0 => 144744)
--- trunk/LayoutTests/fast/regions/mathml-crash.html (rev 0)
+++ trunk/LayoutTests/fast/regions/mathml-crash.html 2013-03-05 10:27:35 UTC (rev 144744)
@@ -0,0 +1,45 @@
+<html>
+<head>
+ <title>Test for MathML crash</title>
+ <script src=""
+ <style>
+ #example-text {
+ -webkit-flow-into: example-text-flow;
+ padding: 0;
+ margin: 0;
+ }
+ .regions {
+ -webkit-flow-from: example-text-flow;
+ border: 1px solid black;
+ width: 200px;
+ height: 50px;
+ }
+ </style>
+</head>
+<body>
+<div>
+ <p>Bug <a href="" [CSS Regions] Crash when MathML used in CSS Regions</p>
+ <p>This test PASSES if it does not CRASH or ASSERT.</p>
+ <div id="example-text">
+ <div>
+ <math>
+ <mrow>
+ <mn>2</mn>
+ <mo>+</mo>
+ <mn>4</mn>
+ </mrow>
+ </math>
+ </div>
+ </div>
+ <div class="regions"></div>
+</div>
+<script type="text/_javascript_">
+if (window.testRunner)
+ testRunner.dumpAsText();
+document.body.offsetTop;
+if (window.testRunner)
+ document.getElementById("example-text").style.display = "none";
+</script>
+<script src=""
+</body>
+</html>
Modified: trunk/Source/WebCore/ChangeLog (144743 => 144744)
--- trunk/Source/WebCore/ChangeLog 2013-03-05 10:05:41 UTC (rev 144743)
+++ trunk/Source/WebCore/ChangeLog 2013-03-05 10:27:35 UTC (rev 144744)
@@ -1,3 +1,33 @@
+2013-03-05 Andrei Bucur <[email protected]>
+
+ [CSS Regions] Crash when MathML used in CSS Regions
+ https://bugs.webkit.org/show_bug.cgi?id=110686
+
+ Reviewed by David Hyatt.
+
+ The MathML blocks trigger a children layout when computing the preferred widths. This happens to determine the preferred
+ logical heights of the children. When the layout reaches the line boxes computation the preferred width of the containing block
+ is requested. Because it wasn't computed, the layout of the children is started again to determine the preferred logical heights.
+ This causes an infinite recursion and triggers a stack overflow.
+
+ The patch introduces a new RAII utility class that disables fragmentation when the constructor is called and restores it
+ on the destructor. This class is used when computing the preferred height for the children of a MathML block.
+
+ Test: fast/regions/mathml-crash.html
+
+ * rendering/RenderObject.cpp:
+ (WebCore::RenderObject::setFlowThreadStateIncludingDescendants): Do not cross RenderFlowThread boundaries when updating the flow thread
+ state flag. The innermost flow threads need to manage their descendants flag values.
+ * rendering/RenderView.cpp:
+ (WebCore::FragmentationDisabler::FragmentationDisabler):
+ (WebCore):
+ (WebCore::FragmentationDisabler::~FragmentationDisabler):
+ * rendering/RenderView.h:
+ (FragmentationDisabler):
+ (WebCore):
+ * rendering/mathml/RenderMathMLBlock.cpp:
+ (WebCore::RenderMathMLBlock::computeChildrenPreferredLogicalHeights):
+
2013-03-05 Mike West <[email protected]>
Cleanup: Move HitTestLocation and HitTestResult into separate files.
Modified: trunk/Source/WebCore/rendering/RenderObject.cpp (144743 => 144744)
--- trunk/Source/WebCore/rendering/RenderObject.cpp 2013-03-05 10:05:41 UTC (rev 144743)
+++ trunk/Source/WebCore/rendering/RenderObject.cpp 2013-03-05 10:27:35 UTC (rev 144744)
@@ -281,6 +281,9 @@
setFlowThreadState(state);
for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
+ // If the child is a fragmentation context it already updated the descendants flag accordingly.
+ if (child->isRenderFlowThread())
+ continue;
ASSERT(state != child->flowThreadState());
child->setFlowThreadStateIncludingDescendants(state);
}
Modified: trunk/Source/WebCore/rendering/RenderView.cpp (144743 => 144744)
--- trunk/Source/WebCore/rendering/RenderView.cpp 2013-03-05 10:05:41 UTC (rev 144743)
+++ trunk/Source/WebCore/rendering/RenderView.cpp 2013-03-05 10:27:35 UTC (rev 144744)
@@ -1147,4 +1147,42 @@
info.addMember(m_legacyPrinting, "legacyPrinting");
}
+FragmentationDisabler::FragmentationDisabler(RenderObject* root)
+{
+ RenderView* renderView = root->view();
+ ASSERT(renderView);
+
+ LayoutState* layoutState = renderView->layoutState();
+
+ m_root = root;
+ m_fragmenting = layoutState && layoutState->isPaginated();
+ m_flowThreadState = m_root->flowThreadState();
+#ifndef NDEBUG
+ m_layoutState = layoutState;
+#endif
+
+ if (layoutState)
+ layoutState->m_isPaginated = false;
+
+ if (m_flowThreadState != RenderObject::NotInsideFlowThread)
+ m_root->setFlowThreadStateIncludingDescendants(RenderObject::NotInsideFlowThread);
+}
+
+FragmentationDisabler::~FragmentationDisabler()
+{
+ RenderView* renderView = m_root->view();
+ ASSERT(renderView);
+
+ LayoutState* layoutState = renderView->layoutState();
+#ifndef NDEBUG
+ ASSERT(m_layoutState == layoutState);
+#endif
+
+ if (layoutState)
+ layoutState->m_isPaginated = m_fragmenting;
+
+ if (m_flowThreadState != RenderObject::NotInsideFlowThread)
+ m_root->setFlowThreadStateIncludingDescendants(m_flowThreadState);
+}
+
} // namespace WebCore
Modified: trunk/Source/WebCore/rendering/RenderView.h (144743 => 144744)
--- trunk/Source/WebCore/rendering/RenderView.h 2013-03-05 10:05:41 UTC (rev 144743)
+++ trunk/Source/WebCore/rendering/RenderView.h 2013-03-05 10:27:35 UTC (rev 144744)
@@ -446,6 +446,20 @@
RenderView* m_view;
};
+class FragmentationDisabler {
+ WTF_MAKE_NONCOPYABLE(FragmentationDisabler);
+public:
+ FragmentationDisabler(RenderObject* root);
+ ~FragmentationDisabler();
+private:
+ RenderObject* m_root;
+ RenderObject::FlowThreadState m_flowThreadState;
+ bool m_fragmenting;
+#ifndef NDEBUG
+ LayoutState* m_layoutState;
+#endif
+};
+
} // namespace WebCore
#endif // RenderView_h
Modified: trunk/Source/WebCore/rendering/mathml/RenderMathMLBlock.cpp (144743 => 144744)
--- trunk/Source/WebCore/rendering/mathml/RenderMathMLBlock.cpp 2013-03-05 10:05:41 UTC (rev 144743)
+++ trunk/Source/WebCore/rendering/mathml/RenderMathMLBlock.cpp 2013-03-05 10:27:35 UTC (rev 144744)
@@ -76,10 +76,13 @@
void RenderMathMLBlock::computeChildrenPreferredLogicalHeights()
{
ASSERT(needsLayout());
-
+
+ // This is ugly, but disable fragmentation when computing the preferred heights.
+ FragmentationDisabler fragmentationDisabler(this);
+
// Ensure a full repaint will happen after layout finishes.
setNeedsLayout(true, MarkOnlyThis);
-
+
RenderView* renderView = view();
bool hadLayoutState = renderView->layoutState();
if (!hadLayoutState)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes