[LayoutNGBlockFragmentation] Crash with "overflow: -webkit-paged-x".
Reported by
babata...@gmail.com,
Aug 31
|
||||||
Issue descriptionUserAgent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3537.2 Safari/537.36 Steps to reproduce the problem: 1. Enable "enable-layout-ng" runtime feature. 2. Open https://ja.wikipedia.org 3. Open devtools. 4. Select "<body>" in "Elements" tab, then add "overflow: -webkit-paged-x" CSS property. What is the expected behavior? The added property is applied. What went wrong? The renderer crashes. See the screencast: https://drive.google.com/file/d/1PThn5HT4xRW8BhEwUooVGQkjwmAJcZfF/view?usp=sharing Did this work before? Yes The crash does not occur without LayoutNG. Does this work in other browsers? Yes Chrome version: 70.0.3537.2 Channel: canary OS Version: 10.0 Flash Version: I don't know why, but other websites including English wikipedia won't crash.
,
Sep 2
,
Sep 3
Thanks for filing the issue! Able to reproduce the issue on reported chrome version 70.0.3537.2 and on the latest canary 70.0.3538.5 using Windows 10 and Ubuntu 14.04. Note: The issue is not seen on Mac 10.13.1 As the issue is seen from the introduction of flag "enable-layout-ng" in M69(69.0.3482.0), hence considering it as Non-Regression and marking it as Untriaged. Requesting the respective team to have a look into this and help in further triaging it.
,
Sep 10
,
Sep 10
Thanks for the great test case! I cannot reproduce it anymore, though. Crashes in: 70.0.3528.4 (the version I happened to be running before upgrading) Doesn't crash in: 70.0.3538.9 (the latest version ATM)
,
Sep 10
I found it suspicious that this got fixed, since I wasn't aware of any recent changes in the area, so I bisected. Turns out this got fixed by https://chromium-review.googlesource.com/1145491 . That's an optimization that stops the test case from crashing (because deep layout is no longer required), but all we need is a slightly more evil testcase, that needs layout after the viewport gets paginated. Attached. The root cause is that we fail to fall back to legacy layout as we should when the viewport gets paginated because of BODY style. So we end up trying to legacy-paginate NG objects, which isn't supported.
,
Sep 10
71.0.3548.0 does not crash with testcase.html, but still crashes with testcase2.html (attached). It crashes only if the browser height is small so that the vertical scrollbar is shown.
,
Sep 10
It will DCHECK-fail first, like this:
#3 0x00007fffe3a0e767 in blink::LayoutBox::OffsetFromLogicalTopOfFirstPage (this=0x29271f0243e8)
at ./../../third_party/blink/renderer/core/layout/layout_box.cc:5667
#4 0x00007fffe3a1b258 in blink::LayoutBox::PageRemainingLogicalHeightForOffset (this=0x29271f0243e8, offset=0px,
page_boundary_rule=blink::LayoutBox::kAssociateWithLatterPage)
at ./../../third_party/blink/renderer/core/layout/layout_box.cc:5897
#5 0x00007fffe3a05e82 in blink::LayoutBox::UpdateFragmentationInfoForChild (this=0x29271f0243e8, child=...)
at ./../../third_party/blink/renderer/core/layout/layout_box.cc:5058
#6 0x00007fffe3a0587a in blink::LayoutBlock::LayoutPositionedObject (this=0x29271f0243e8, positioned_object=0x29271f024530,
relayout_children=false, info=blink::LayoutBlock::kDefaultLayout)
at ./../../third_party/blink/renderer/core/layout/layout_block.cc:877
#7 0x00007fffe39da33f in blink::LayoutBlock::LayoutPositionedObjects (this=0x29271f0243e8, relayout_children=false,
info=blink::LayoutBlock::kDefaultLayout) at ./../../third_party/blink/renderer/core/layout/layout_block.cc:790
#8 0x00007fffe3cacc97 in blink::NGBlockNode::CopyFragmentDataToLayoutBox (this=0x7fffa879a1a8, constraint_space=...,
layout_result=...) at ../../third_party/blink/renderer/core/layout/ng/ng_block_node.cc:512
#9 0x00007fffe3cac40c in blink::NGBlockNode::FinishLayout (this=0x7fffa879a1a8, constraint_space=..., break_token=0x0,
layout_result=...) at ../../third_party/blink/renderer/core/layout/ng/ng_block_node.cc:277
#10 0x00007fffe3caad87 in blink::NGBlockNode::Layout (this=0x7fffa879a1a8, constraint_space=..., break_token=0x0)
at ../../third_party/blink/renderer/core/layout/ng/ng_block_node.cc:214
#11 0x00007fffe3c35a9b in blink::NGLayoutInputNode::Layout (this=0x7fffa879a1a8, space=..., break_token=0x0)
at ./../../third_party/blink/renderer/core/layout/ng/ng_layout_input_node.cc:143
#12 0x00007fffe3ca2984 in blink::NGBlockLayoutAlgorithm::HandleInflow (this=0x7fffa879bc08, child=..., child_break_token=0x0,
previous_inflow_position=0x7fffa879a538, previous_inline_break_token=0x7fffa879a4b8)
at ../../third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.cc:1079
An out-of-flow positioned object needs to be involved to trigger legacy pagination. Furthermore, we need to be inside a table, so that the layout state has set its layout object to the LayoutTableSection.
Things have already gone wrong when LayoutBox::OffsetFromLogicalTopOfFirstPage() calls itself recursively up the object ancestry, to find the layout object stored in the layout state. We're not going to find the LayoutTableSection, because ContainingBlock() will ignore it (a LayoutTableSection isn't a block). So we'll reach the root and walk past it, and eventually attempt to dereference a null-pointer.
The first thing to fix here is to avoid this situation altogether in normal LayoutNG mode. We should force legacy layout (like we intend, but fail to do) when there's block fragmentation involved.
The long-term fix is to make NG block fragmentation (LayoutNGBlockFragmentation feature flag) handle this correctly.
,
Sep 10
The following revision refers to this bug: https://chromium.googlesource.com/chromium/src.git/+/e26b06faf4913461fd9f01c2f2bdd26581a177aa commit e26b06faf4913461fd9f01c2f2bdd26581a177aa Author: Morten Stenshorne <mstensho@chromium.org> Date: Mon Sep 10 17:23:54 2018 [LayoutNG] Properly fall back to legacy when BODY gets paginated. LayoutNG block fragmentation doesn't cope with pagination of out-of-flow positioned objects, but in this case we shouldn't even be there, because block fragmentation should trigger fall-back to legacy layout. One check was too strict to make that happen. Bug: 879467 Change-Id: I97ef4435ef5dc4a4122c97b58c22c3adf88fd17f Reviewed-on: https://chromium-review.googlesource.com/1215026 Commit-Queue: Emil A Eklund <eae@chromium.org> Reviewed-by: Emil A Eklund <eae@chromium.org> Cr-Commit-Position: refs/heads/master@{#589960} [modify] https://crrev.com/e26b06faf4913461fd9f01c2f2bdd26581a177aa/third_party/WebKit/LayoutTests/TestExpectations [add] https://crrev.com/e26b06faf4913461fd9f01c2f2bdd26581a177aa/third_party/WebKit/LayoutTests/fast/pagination/body-make-paginated-table-abspos-crash.html [modify] https://crrev.com/e26b06faf4913461fd9f01c2f2bdd26581a177aa/third_party/blink/renderer/core/css/resolver/style_adjuster.cc
,
Sep 11
It's now fixed in regular LayoutNG configurations, but still fails when LayoutNGBlockFragmentation is enabled, since the actual problem hasn't been fixed. Leaving the bug open.
,
Dec 14
,
Jan 15
On second thought it doesn't make a lot of sense to keep this bug open. The only thing left here is to make it work for LayoutNGBlockFragmentation, which isn't anywhere close to finished anyway. |
||||||
►
Sign in to add a comment |
||||||
Comment 1 by babata...@gmail.com
, Aug 31175 bytes
175 bytes View Download