Remove floating objects from descendants of subtree roots

The pre-layout for orthogonal flow clears floats from its containing
block in [1]. However, this can cause trouble for
markAllDescendantsWithFloatsForLayout() to mark descendants for layout.

When preceding floats overhanging to following blocks are gone, such
floats are referred from multiple following blocks including
descendants. Failure to mark descendants for layout may leave preceding
floats.

This patch ensures such floats are removed.

[1] https://codereview.chromium.org/2025543002

BUG=698455

Review-Url: https://codereview.chromium.org/2737253003
Cr-Commit-Position: refs/heads/master@{#456300}
diff --git a/third_party/WebKit/LayoutTests/fast/writing-mode/orthogonal-writing-modes-floats-crash-3.html b/third_party/WebKit/LayoutTests/fast/writing-mode/orthogonal-writing-modes-floats-crash-3.html
new file mode 100644
index 0000000..5cc35ba
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/writing-mode/orthogonal-writing-modes-floats-crash-3.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+
+<!-- Disable auto scrollbars, to avoid an extra layout pass, which
+     would hide the bug. The original fuzzer test instead used an
+     insane margin on an atomic inline to make sure the scrollbars
+     stayed put. -->
+<style>body { overflow:scroll; }</style>
+
+<p>PASS if no crash.</p>
+
+<div id="rightFloat" style="float:right; height:40px;"></div>
+<div style="float:left; height:300px;"></div>
+<span>
+    <div id="inlineBlock2" style="display:none; width:30px; height:300px;"></div>
+    <span id="inline" style="display:none;">x</span>
+</span>
+<div>
+    <div style="height:40px;"></div>
+    <div style="display:table; writing-mode:vertical-lr;">
+        <div>
+            <div id="dummyBlock" style="display:none;"></div>
+        </div>
+        <div id="inlineBlock1" style="display:inline-block; width:30px; height:300px;"></div>
+    </div>
+</div>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script>
+if (window.testRunner)
+  testRunner.dumpAsText();
+test(() => {
+  document.body.offsetTop;
+  document.getElementById("inlineBlock1").style.display = "none";
+  document.getElementById("inlineBlock2").style.display = "inline-block";
+  document.body.offsetTop;
+  document.getElementById("rightFloat").style.display = "none";
+  document.getElementById("dummyBlock").style.display = "block";
+  document.body.offsetTop;
+  document.getElementById("inline").style.display = "inline";
+}, "no crash or assertion failure");
+</script>
diff --git a/third_party/WebKit/Source/core/frame/FrameView.cpp b/third_party/WebKit/Source/core/frame/FrameView.cpp
index 781576b..d8dac0e2 100644
--- a/third_party/WebKit/Source/core/frame/FrameView.cpp
+++ b/third_party/WebKit/Source/core/frame/FrameView.cpp
@@ -2181,8 +2181,9 @@
   // FloatingObjects.
   if (LayoutBlock* cb = root.containingBlock()) {
     if ((cb->normalChildNeedsLayout() || cb->selfNeedsLayout()) &&
-        cb->isLayoutBlockFlow())
-      toLayoutBlockFlow(cb)->removeFloatingObjects();
+        cb->isLayoutBlockFlow()) {
+      toLayoutBlockFlow(cb)->removeFloatingObjectsFromDescendants();
+    }
   }
 }