Copied: branches/chromium/1364/LayoutTests/fast/multicol/recursive-split-flow-crash-expected.txt (from rev 138988, trunk/LayoutTests/fast/multicol/recursive-split-flow-crash-expected.txt) (0 => 139653)
--- branches/chromium/1364/LayoutTests/fast/multicol/recursive-split-flow-crash-expected.txt (rev 0)
+++ branches/chromium/1364/LayoutTests/fast/multicol/recursive-split-flow-crash-expected.txt 2013-01-14 21:22:23 UTC (rev 139653)
@@ -0,0 +1,3 @@
+Bug 101984: Heap-buffer-overflow in WebCore::RenderBlock::clone.
+Test passes if it does not crash.
+
Copied: branches/chromium/1364/LayoutTests/fast/multicol/recursive-split-flow-crash.html (from rev 138988, trunk/LayoutTests/fast/multicol/recursive-split-flow-crash.html) (0 => 139653)
--- branches/chromium/1364/LayoutTests/fast/multicol/recursive-split-flow-crash.html (rev 0)
+++ branches/chromium/1364/LayoutTests/fast/multicol/recursive-split-flow-crash.html 2013-01-14 21:22:23 UTC (rev 139653)
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html>
+Bug 101984: Heap-buffer-overflow in WebCore::RenderBlock::clone.<br />
+Test passes if it does not crash.
+<body>
+<table>
+<div class="container">
+<div class="testClass" id="test1">
+</div>
+<div class="testClass">
+<div>
+<i id="test2"></i>
+</div>
+</div>
+</div>
+</table>
+<script>
+if (window.testRunner)
+ testRunner.dumpAsText();
+
+document.head.appendChild(document.createElement("style"));
+var styleSheet0 = document.styleSheets[0];
+var test1 = document.getElementById("test1");
+var test2 = document.getElementById("test2");
+
+
+document.execCommand("SelectAll", true);
+styleSheet0.insertRule('.testClass { -webkit-column-span: all ; }', 0);
+test1.appendChild(test2);
+styleSheet0.insertRule('.testClass::first-letter { border-style: none; }', 0);
+styleSheet0.insertRule('.container { -webkit-column-axis: vertical; }', 0);
+</script>
+</body>
+</html>
\ No newline at end of file
Modified: branches/chromium/1364/Source/WebCore/rendering/RenderBlock.cpp (139652 => 139653)
--- branches/chromium/1364/Source/WebCore/rendering/RenderBlock.cpp 2013-01-14 21:21:37 UTC (rev 139652)
+++ branches/chromium/1364/Source/WebCore/rendering/RenderBlock.cpp 2013-01-14 21:22:23 UTC (rev 139653)
@@ -70,6 +70,7 @@
#include <wtf/MemoryInstrumentationHashMap.h>
#include <wtf/MemoryInstrumentationHashSet.h>
#include <wtf/MemoryInstrumentationListHashSet.h>
+#include <wtf/TemporaryChange.h>
using namespace std;
using namespace WTF;
@@ -117,6 +118,8 @@
static int gDelayUpdateScrollInfo = 0;
static DelayedUpdateScrollInfoSet* gDelayedUpdateScrollInfoSet = 0;
+static bool gIsInColumnFlowSplit = false;
+
bool RenderBlock::s_canPropagateFloatIntoSibling = false;
// This class helps dispatching the 'overflow' event on layout change. overflow can be set on RenderBoxes, yet the existing code
@@ -829,30 +832,33 @@
beforeChild = beforeChild->nextSibling();
// Check for a spanning element in columns.
- RenderBlock* columnsBlockAncestor = columnsBlockForSpanningElement(newChild);
- if (columnsBlockAncestor) {
- // We are placing a column-span element inside a block.
- RenderBlock* newBox = createAnonymousColumnSpanBlock();
+ if (!gIsInColumnFlowSplit) {
+ RenderBlock* columnsBlockAncestor = columnsBlockForSpanningElement(newChild);
+ if (columnsBlockAncestor) {
+ TemporaryChange<bool> isInColumnFlowSplit(gIsInColumnFlowSplit, true);
+ // We are placing a column-span element inside a block.
+ RenderBlock* newBox = createAnonymousColumnSpanBlock();
- if (columnsBlockAncestor != this) {
- // We are nested inside a multi-column element and are being split by the span. We have to break up
- // our block into continuations.
- RenderBoxModelObject* oldContinuation = continuation();
+ if (columnsBlockAncestor != this) {
+ // We are nested inside a multi-column element and are being split by the span. We have to break up
+ // our block into continuations.
+ RenderBoxModelObject* oldContinuation = continuation();
- // When we split an anonymous block, there's no need to do any continuation hookup,
- // since we haven't actually split a real element.
- if (!isAnonymousBlock())
- setContinuation(newBox);
+ // When we split an anonymous block, there's no need to do any continuation hookup,
+ // since we haven't actually split a real element.
+ if (!isAnonymousBlock())
+ setContinuation(newBox);
- splitFlow(beforeChild, newBox, newChild, oldContinuation);
+ splitFlow(beforeChild, newBox, newChild, oldContinuation);
+ return;
+ }
+
+ // We have to perform a split of this block's children. This involves creating an anonymous block box to hold
+ // the column-spanning |newChild|. We take all of the children from before |newChild| and put them into
+ // one anonymous columns block, and all of the children after |newChild| go into another anonymous block.
+ makeChildrenAnonymousColumnBlocks(beforeChild, newBox, newChild);
return;
}
-
- // We have to perform a split of this block's children. This involves creating an anonymous block box to hold
- // the column-spanning |newChild|. We take all of the children from before |newChild| and put them into
- // one anonymous columns block, and all of the children after |newChild| go into another anonymous block.
- makeChildrenAnonymousColumnBlocks(beforeChild, newBox, newChild);
- return;
}
bool madeBoxesNonInline = false;