Skip to content
Permalink
Browse files
Folding anonymous blocks should not result in deleting content.
https://bugs.webkit.org/show_bug.cgi?id=184339
<rdar://problem/37327428>

Reviewed by Antti Koivisto.

Source/WebCore:

While folding multiple anonymous blocks (moving the children from next sibling over to previous sibling)
we should ensure that the block we are about to destroy does not gain new descendants.
In case of 4 sibling anonymous blocks (A B C D), while destroying B
1. we move C's children to A and destroy C.
2. While destroying C, we notice B and C as sibling anonymous blocks and we move
D's children over to B (even though B is going to be destroyed as we climb back on the stack).

In this patch, B is detached from the tree before we start moving renderers around so that a subsequent folding won't
find B anymore as a candidate.

Test: fast/block/crash-while-folding-anonymous-blocks.html

* rendering/updating/RenderTreeBuilderBlock.cpp:
(WebCore::RenderTreeBuilder::Block::detach):

LayoutTests:

* fast/block/crash-when-subtree-is-still-attached-expected.txt: Progressing. This test does not
intend to remove "foobar" text at all.
* fast/block/crash-while-folding-anonymous-blocks-expected.txt: Added.
* fast/block/crash-while-folding-anonymous-blocks.html: Added.


Canonical link: https://commits.webkit.org/199896@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@230313 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
alanbujtas committed Apr 5, 2018
1 parent e734c27 commit ad326c64135cbf871e05d7b99b570df147e2e30d
Showing 6 changed files with 80 additions and 9 deletions.
@@ -1,3 +1,16 @@
2018-04-05 Zalan Bujtas <zalan@apple.com>

Folding anonymous blocks should not result in deleting content.
https://bugs.webkit.org/show_bug.cgi?id=184339
<rdar://problem/37327428>

Reviewed by Antti Koivisto.

* fast/block/crash-when-subtree-is-still-attached-expected.txt: Progressing. This test does not
intend to remove "foobar" text at all.
* fast/block/crash-while-folding-anonymous-blocks-expected.txt: Added.
* fast/block/crash-while-folding-anonymous-blocks.html: Added.

2018-03-21 Ryan Haddad <ryanhaddad@apple.com>

Rebaseline tests for High Sierra.
@@ -1,3 +1,4 @@
PASS if
no crash.
foobar

@@ -0,0 +1,33 @@
<span id=foo9><div id=foo7></div></span><div id=foo1></div><div id=foo2></div><div id=foo3></div><span id=foo12><div id=foo10></div></span><div id=foo4></div><div id=foo5></div><div id=foo6></div><span id=foo11><table><colgroup><col></colgroup></table><div id=foo8></div></span><script>
if (window.testRunner)
testRunner.dumpAsText();
// Setting up 3 continuations in separate blocks.
document.body.offsetHeight;

let di = document.createElement("div");
foo2.appendChild(di);
foo2.style.display = "inline";
document.body.offsetHeight;

foo1.remove();
foo3.remove();
document.body.offsetHeight;

foo2.remove();
document.body.offsetHeight;

let di2 = document.createElement("div");
foo5.appendChild(di2);
foo5.style.display = "inline";
document.body.offsetHeight;

foo4.remove();
foo6.remove();
foo5.remove();
foo7.remove();
foo9.remove();
foo10.remove();
document.body.offsetHeight;
foo12.remove();
document.body.offsetHeight;
</script>
@@ -1,3 +1,26 @@
2018-04-05 Zalan Bujtas <zalan@apple.com>

Folding anonymous blocks should not result in deleting content.
https://bugs.webkit.org/show_bug.cgi?id=184339
<rdar://problem/37327428>

Reviewed by Antti Koivisto.

While folding multiple anonymous blocks (moving the children from next sibling over to previous sibling)
we should ensure that the block we are about to destroy does not gain new descendants.
In case of 4 sibling anonymous blocks (A B C D), while destroying B
1. we move C's children to A and destroy C.
2. While destroying C, we notice B and C as sibling anonymous blocks and we move
D's children over to B (even though B is going to be destroyed as we climb back on the stack).

In this patch, B is detached from the tree before we start moving renderers around so that a subsequent folding won't
find B anymore as a candidate.

Test: fast/block/crash-while-folding-anonymous-blocks.html

* rendering/updating/RenderTreeBuilderBlock.cpp:
(WebCore::RenderTreeBuilder::Block::detach):

2018-04-05 Andy Estes <aestes@apple.com>

Mark Payment Request as "Supported" in features.json
@@ -280,9 +280,14 @@ RenderPtr<RenderObject> RenderTreeBuilder::Block::detach(RenderBlock& parent, Re

// If this child is a block, and if our previous and next siblings are both anonymous blocks
// with inline content, then we can fold the inline content back together.
RenderObject* prev = oldChild.previousSibling();
RenderObject* next = oldChild.nextSibling();
bool canMergeAnonymousBlocks = canMergeContiguousAnonymousBlocks(oldChild, prev, next);
auto prev = makeWeakPtr(oldChild.previousSibling());
auto next = makeWeakPtr(oldChild.nextSibling());
bool canMergeAnonymousBlocks = canMergeContiguousAnonymousBlocks(oldChild, prev.get(), next.get());

parent.invalidateLineLayoutPath();

auto takenChild = m_builder.detachFromRenderElement(parent, oldChild);

if (canMergeAnonymousBlocks && prev && next) {
prev->setNeedsLayoutAndPrefWidthsRecalc();
RenderBlock& nextBlock = downcast<RenderBlock>(*next);
@@ -320,15 +325,10 @@ RenderPtr<RenderObject> RenderTreeBuilder::Block::detach(RenderBlock& parent, Re
// Delete the now-empty block's lines and nuke it.
nextBlock.deleteLines();
m_builder.destroy(nextBlock);
next = nullptr;
}
}

parent.invalidateLineLayoutPath();

auto takenChild = m_builder.detachFromRenderElement(parent, oldChild);

RenderObject* child = prev ? prev : next;
RenderObject* child = prev ? prev.get() : next.get();
if (canMergeAnonymousBlocks && child && !child->previousSibling() && !child->nextSibling() && parent.canDropAnonymousBlockChild()) {
// The removal has knocked us down to containing only a single anonymous
// box. We can pull the content right back up into our box.

0 comments on commit ad326c6

Please sign in to comment.