WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
RESOLVED FIXED
268770
CVE-2024-40782
Nullptr crash due to `display:ruby block` and continuations
https://bugs.webkit.org/show_bug.cgi?id=268770
Summary
Nullptr crash due to `display:ruby block` and continuations
John Wilander
Reported
2024-02-05 12:06:50 PST
Created
attachment 469728
[details]
Repro case See attached repro case. Looks related to
https://bugs.webkit.org/show_bug.cgi?id=268768
, possibly even dupes. <
rdar://121960530
>
Attachments
Repro case
(2.43 KB, text/plain)
2024-02-05 12:06 PST
,
John Wilander
no flags
Details
Reduced test case
(433 bytes, text/html)
2024-03-13 09:46 PDT
,
Claudio Saavedra
no flags
Details
Minimized testcase (similar to original release backtrace)
(434 bytes, text/html)
2024-03-22 11:55 PDT
,
Frédéric Wang (:fredw)
no flags
Details
Minimized testcase (debug assert)
(128 bytes, text/html)
2024-03-22 12:23 PDT
,
Frédéric Wang (:fredw)
no flags
Details
Release crash / debug assert with inline ruby
(301 bytes, text/html)
2024-04-02 02:31 PDT
,
Frédéric Wang (:fredw)
no flags
Details
Patch putting children of ruby bases inside an anonymous inline block
(2.50 KB, patch)
2024-04-02 02:49 PDT
,
Frédéric Wang (:fredw)
no flags
Details
Formatted Diff
Diff
View All
Add attachment
proposed patch, testcase, etc.
Rob Buis
Comment 1
2024-02-16 03:56:24 PST
For me this hits an assert (but likely there are multiple problems): ASSERTION FAILED: parent.firstChild()->style().display() == DisplayType::Ruby /Users/rbuis/work/WebKit/Source/WebCore/rendering/updating/RenderTreeBuilderRuby.cpp(277) : RenderElement &WebCore::RenderTreeBuilder::Ruby::findOrCreateParentForStyleBasedRubyChild(RenderElement &, const RenderObject &, RenderObject *&) Minimized testcase: <script> function main() { document.caretRangeFromPoint().insertNode(caption); } </script> <body onload="main()"> <ruby style="position: absolute"> <table> <caption id="caption"> <ol></ol> </caption> </table> </ruby> </body>
Claudio Saavedra
Comment 2
2024-03-11 08:41:38 PDT
I have been investigating the Debug assertion that Rob mentions. First of all, should be mentioned that that assertion crash is not a security issue, as it only happens in Debug. However, investigating it I realized that the assertion is not correct and that it also causes a rendering issue, so I filed that in a separate bug report and submitted a MR for it (see
https://bugs.webkit.org/show_bug.cgi?id=270792
and its MR for details). Irrespective of that, there's still a crash with the original test case that needs to be investigated, so working on that now.
Claudio Saavedra
Comment 3
2024-03-13 09:46:11 PDT
Created
attachment 470346
[details]
Reduced test case Reduced test case that causes release and debug crashes.
Claudio Saavedra
Comment 4
2024-03-13 09:59:18 PDT
This bug is caused by an assumption in RenderTreeBuilder::Ruby::findOrCreateParentForStyleBasedRubyChild() that if we have a RubyBlock renderer with children, these children can only be Ruby boxes. This assumption is enforced with an ASSERT() that causes the Debug build crashes, but in Release what happens is that the method instead continues out of the code block that handles RubyBlocks, and moves to handle other cases. That can cause rendering issues, as children can be attached to the wrong parent (see
https://bugs.webkit.org/show_bug.cgi?id=270792
), but can also cause us to mix inline and block renderers where we shouldn't. Fixing this involves making sure that children that are to be attached to RubyBlocks are properly handled in the case of continuations, finding the right candidate parent, instead of just appending it to the first one. When I filed 270792 I only took care of the Debug assert, but that was incomplete, as the test case above can be reduced to one that also crashes in Release, so it's better to close that bug and handle everything here.
Claudio Saavedra
Comment 5
2024-03-13 10:04:59 PDT
Pull request:
https://github.com/WebKit/WebKit-security/pull/60
Claudio Saavedra
Comment 6
2024-03-13 11:18:31 PDT
To aid review, here is a bit of debugging info on this. With the reduced case I attached, this is the state of the render tree before hitting the Debug assertion (the highlighted item is the ruby parent): (B)lock/(I)nline/I(N)line-block, (A)bsolute/Fi(X)ed/(R)elative/Stic(K)y, (F)loating, (O)verflow clip, Anon(Y)mous, (G)enerated, has(L)ayer, hasLayer(S)crollableArea, (C)omposited, Content-visibility:(H)idden/(A)uto, (S)kipped content, (+)Dirty style, (+)Dirty layout B---YGLSC-- -+ RenderView at (0,0) size 800x563 renderer (0x7ff69a0002c0) layout box ((nil)) layout->[normal child][positioned child] B-----LS--- -+ HTML RenderBlock at (0,0) size 800x563 renderer (0x7ff69a0015c0) layout box ((nil)) node (0x7ff69a000e50) layout->[normal child] B---------- -+ BODY RenderBody at (8,8) size 784x547 renderer (0x7ff69a001860) layout box ((nil)) node (0x7ff69a001050) layout->[self][normal child] BA----L---- -+* RUBY RenderBlock at (0,0) size 0x0 renderer (0x7ff69a003500) layout box ((nil)) node (0x7ff69a004360) layout->[self][normal child] B---YG----- -+ RenderBlock at (0,0) size 0x0 renderer (0x7ff69a006600) layout box ((nil)) layout->[self][normal child] I---YG----- -+ RenderInline renderer (0x7ff69a006130) layout box ((nil)) layout->[self][normal child] I---YG----- -+ RenderInline renderer (0x7ff69a006230) layout box ((nil)) layout->[self][normal child] I---------- -+ CAPTION RenderInline renderer (0x7ff69a006030) layout box ((nil)) node (0x7ff69a004780) continuation->(0x7ff69a0064b0) layout->[self][normal child] I---------- -+ #text RenderText renderer (0x7ff69a006330) layout box ((nil)) node (0x7ff69a004800) length->(21) "\n " layout->[self] B---YG----- -+ RenderBlock at (0,0) size 0x0 renderer (0x7ff69a0064b0) layout box ((nil)) continuation->(0x7ff69a0068a0) layout->[self][normal child] B---------- -+ OL RenderBlock at (0,0) size 0x0 renderer (0x7ff69a0037a0) layout box ((nil)) node (0x7ff69a004950) layout->[self] B---YG----- -+ RenderBlock at (0,0) size 0x0 renderer (0x7ff69a006750) layout box ((nil)) layout->[self][normal child] I---------- -+ CAPTION RenderInline renderer (0x7ff69a0068a0) layout box ((nil)) node (0x7ff69a004780) layout->[self] The child that we are trying to attach is a TEXT renderer that should go after the CAPTION. Here is the DOM tree with the child node highlighted: BODY 0x7ff69a001050 (renderer 0x7ff69a001860) #text 0x7ff69a004280 "\n " RUBY 0x7ff69a004360 (renderer 0x7ff69a003500) STYLE=position:absolute #text 0x7ff69a0042f0 "\n " CAPTION 0x7ff69a004780 (renderer 0x7ff69a006030) #text 0x7ff69a004800 "\n " OL 0x7ff69a004950 (renderer 0x7ff69a0037a0) #text 0x7ff69a004870 "\n " #text 0x7ff69a0048e0 "\n " * #text 0x7ff69a004b70 "AAAA\n " DIV 0x7ff69a004460 (renderer (nil)) STYLE=display:contents #text 0x7ff69a004560 "\n " TABLE 0x7ff69a004640 (renderer (nil)) #text 0x7ff69a0045d0 "\n " #text 0x7ff69a004a90 "\n " #text 0x7ff69a004b00 "\n \n\n" The render block 0x7ff69a006600 is an anonymous block that was created earlier, when the OL element was being attached after a text element. Text is inline, but OL is block, so continuations are needed. The code that creates the anonymous continuation blocks determines that the containing block is the RUBY block 0x7ff69a004360, so that's where the pre/post blocks are created, and the block that contains the OL element. The code where the assertion is hit: if (parent.style().display() == DisplayType::RubyBlock && parent.firstChild()) { // See if we have an anonymous ruby box already. ASSERT(parent.firstChild()->style().display() == DisplayType::Ruby); return downcast<RenderElement>(*parent.firstChild()); } If the assertion is compiled out (as in Release), we always return the first child of the parent. In this case, that would be the "pre" block of the continuation, 0x7ff69a003500, but that is not correct, as the text renderer for 0x7ff69a004b70 should be attached after the OL (that is, in the "post" block, 0x7ff69a006750). Finding the proper block where the child should be attached fixes the assertion crash, and also other Release crashes that happen later during layout if inline and block renderers are mixed.
Frédéric Wang (:fredw)
Comment 7
2024-03-22 04:54:03 PDT
TL;DR: The crash from the original repro case (
attachment 469728
[details]
) is due to destroyAndCleanUpAnonymousWrappers incorrectly being called with a detached subtree, whose root is an anonymous rubyBase created in findOrCreateParentForStyleBasedRubyChild that is inserted by attachToRenderElementInternal with the following bad configuration: RUBY RenderBlock at (648,2920) size 34x2960 renderer (0x7f4e9e010110) layout box ((nil)) node (0x7f4e9e00d120) layout->[self][normal child] [parent] ---------> RenderInline renderer (0x7f4e9e00f380) layout box ((nil)) layout->[normal child] RenderInline renderer (0x7f4e9e00f420) layout box ((nil)) layout->[normal child] CAPTION RenderInline renderer (0x7f4e9e00f2e0) layout box ((nil)) node (0x7f4e9e00d650) continuation->(0x7f4e9e021b70) layout->[self][normal child] #text RenderText renderer (0x7f4e9e00f5d0) layout box ((nil)) node (0x7f4e9e00d4d0) length->(2) "\n\n" layout->[self] #text RenderText renderer (0x7f4e9e00ec70) layout box ((nil)) node (0x7f4e9e00c400) length->(5) "AAAA\n" layout->[self] [beforeChild]-----> #text RenderText renderer (0x7f4e9e00f560) layout box ((nil)) node (0x7f4e9e00d3b0) length->(1) "\n" layout->[self] This is happening because `<ruby>` is a DisplayType::RubyBlock and RenderTreeBuilder::attachInternal assumes that in that case all the children are wrapped in a DisplayType::Ruby anonymous child (this is
https://www.w3.org/TR/css-ruby-1/#block-ruby
), which is not the case for beforeChild here. So this is indeed related to the debug assert commented above, although talking with Claudio the proper fix is probably to ensure the ruby tree structure is "good" rather than trying to make things work with the current bad structure. We'll provide more details later. More debugging details follows. ******************************************************************************** The is the backtrace of the original release assert: Thread 1 received signal SIGSEGV, Segmentation fault. (rr) bt #0 operator() (__closure=<optimized out>, __closure=<optimized out>) at /home/fred/src-obj/WebKit/Source/WebCore/rendering/updating/RenderTreeBuilder.cpp:818 #1 WebCore::RenderTreeBuilder::destroyAndCleanUpAnonymousWrappers(WebCore::RenderObject&) (this=0x7ffcdfc2f7b0, rendererToDestroy=...) at /home/fred/src-obj/WebKit/Source/WebCore/rendering/updating/RenderTreeBuilder.cpp:828 #2 0x00007f4f2731aa65 in WebCore::RenderTreeUpdater::tearDownTextRenderer(WebCore::Text&, WebCore::RenderTreeBuilder&) (text=..., builder=<optimized out>) at /home/fred/src-obj/WebKit/Source/WebCore/rendering/updating/RenderTreeUpdater.cpp:779 #3 0x00007f4f2731ed83 in WebCore::RenderTreeUpdater::tearDownRenderers(WebCore::Element&, WebCore::RenderTreeUpdater::TeardownType, WebCore::RenderTreeBuilder&) (root=..., teardownType=<optimized out>, builder=...) at /home/fred/src-obj/WebKit/Source/WebCore/rendering/updating/RenderTreeUpdater.cpp:762 #4 0x00007f4f27320c15 in WebCore::RenderTreeUpdater::updateElementRenderer(WebCore::Element&, WebCore::Style::ElementUpdate const&) (this=this@entry=0x7ffcdfc2f780, element=..., elementUpdate=...) at /home/fred/src-obj/WebKit/Source/WebCore/rendering/updating/RenderTreeUpdater.cpp:424 #5 0x00007f4f27322cb1 in WebCore::RenderTreeUpdater::updateRenderTree(WebCore::ContainerNode&) (this=this@entry=0x7ffcdfc2f780, root=<optimized out>) at /home/fred/src-obj/WebKit/Source/WebCore/rendering/updating/RenderTreeUpdater.cpp:262 #6 0x00007f4f2732306b in WebCore::RenderTreeUpdater::commit(std::unique_ptr<WebCore::Style::Update, std::default_delete<WebCore::Style::Update> >) (this=0x7ffcdfc2f780, styleUpdate=std::unique_ptr<WebCore::Style::Update> = {...}) at /home/fred/src-obj/WebKit/Source/WebCore/rendering/updating/RenderTreeUpdater.cpp:127 #7 0x00007f4f26386411 in WebCore::Document::updateRenderTree(std::unique_ptr<WebCore::Style::Update, std::default_delete<WebCore::Style::Update> >) (this=this@entry=0x7f4ead141c00, styleUpdate=std::unique_ptr<WebCore::Style::Update> = {...}) at /usr/include/c++/11/bits/unique_ptr.h:172 #8 0x00007f4f263bafce in WebCore::Document::resolveStyle(WebCore::Document::ResolveStyleType) (this=this@entry=0x7f4ead141c00, type=<optimized out>, type@entry=WebCore::Document::ResolveStyleType::Normal) at /usr/include/c++/11/bits/unique_ptr.h:172 #9 0x00007f4f263bb475 in WebCore::Document::updateStyleIfNeeded() (this=this@entry=0x7f4ead141c00) at /home/fred/src-obj/WebKit/Source/WebCore/dom/Document.cpp:2685 #10 0x00007f4f263c4354 in WebCore::Document::implicitClose() (this=this@entry=0x7f4ead141c00) at /home/fred/src-obj/WebKit/Source/WebCore/dom/Document.cpp:3805 #11 0x00007f4f269d8ff4 in WebCore::FrameLoader::checkCallImplicitClose() (this=0x7f4f050b4e00) at /home/fred/src-obj/WebKit/Source/WebCore/loader/FrameLoader.cpp:1051 #12 0x00007f4f269eb98c in WebCore::FrameLoader::checkCompleted() (this=0x7f4f050b4e00) at /home/fred/src-obj/WebKit/Source/WebCore/loader/FrameLoader.cpp:988 #13 0x00007f4f26a7eafc in WebCore::CachedResourceLoader::loadDone(WebCore::LoadCompletionType, bool) (this=0x7f4f050c0bc0, type=type@entry=WebCore::LoadCompletionType::Finish, shouldPerformPostLoadActions=shouldPerformPostLoadActions@entry=true) at /home/fred/src-obj/WebKit/WebKitBuild/RelWithDebInfo/WTF/Headers/wtf/RawPtrTraits.h:44 #14 0x00007f4f26a3ffef in WebCore::SubresourceLoader::notifyDone(WebCore::LoadCompletionType) (this=this@entry=0x7f4f052417c0, type=type@entry=WebCore::LoadCompletionType::Finish) at /home/fred/src-obj/WebKit/WebKitBuild/RelWithDebInfo/WTF/Headers/wtf/RawPtrTraits.h:44 #15 0x00007f4f26a4b83a in WebCore::SubresourceLoader::notifyDone(WebCore::LoadCompletionType) (type=WebCore::LoadCompletionType::Finish, this=0x7f4f052417c0) at /home/fred/src-obj/WebKit/Source/WebCore/loader/ResourceLoader.h:145 #16 WebCore::SubresourceLoader::didFinishLoading(WebCore::NetworkLoadMetrics const&) (this=0x7f4f052417c0, networkLoadMetrics=...) at /home/fred/src-obj/WebKit/Source/WebCore/loader/SubresourceLoader.cpp:784 It's happening because RenderTreeBuilder::destroyAndCleanUpAnonymousWrappers is called for a detached subtree: (rr) p showRenderTree(destroyRoot) I---YG----- -+* RenderInline renderer (0x7f4e9e022100) layout box ((nil)) layout->[self][normal child] I---YG----- -+ RenderInline renderer (0x7f4e9e021cb0) layout box ((nil)) layout->[self][normal child] I---------- -+ #text RenderText renderer (0x7f4e9e00ece0) layout box ((nil)) node (0x7f4e9e00d350) length->(1) "\n" layout->[self] This is the callback for where destroyRoot was initially attached (rr) watch -l destroyRoot->m_parent (rr) reverse-continue Thread 1 hit Hardware watchpoint 1: -location destroyRoot->m_parent Old value = {m_impl = {m_ptr = 0x7f4f053b5360}} New value = {m_impl = {m_ptr = 0x0}} (rr) bt #0 0x00007f4f27189a07 in std::swap<WTF::SingleThreadWeakPtrImpl*>(WTF::SingleThreadWeakPtrImpl*&, WTF::SingleThreadWeakPtrImpl*&) (__b=<synthetic pointer>: <optimized out>, __a=@0x7f4e9e022120: 0x0) at /usr/include/c++/11/bits/move.h:205 #1 WTF::RawPtrTraits<WTF::SingleThreadWeakPtrImpl>::swap(WTF::SingleThreadWeakPtrImpl*&, WTF::SingleThreadWeakPtrImpl*&) (b=<synthetic pointer>: <optimized out>, a=@0x7f4e9e022120: 0x0) at /home/fred/src-obj/WebKit/WebKitBuild/RelWithDebInfo/WTF/Headers/wtf/RawPtrTraits.h:43 #2 WTF::RefPtr<WTF::SingleThreadWeakPtrImpl, WTF::RawPtrTraits<WTF::SingleThreadWeakPtrImpl>, WTF::DefaultRefDerefTraits<WTF::SingleThreadWeakPtrImpl> >::swap<WTF::SingleThreadWeakPtrImpl, WTF::RawPtrTraits<WTF::SingleThreadWeakPtrImpl>, WTF::DefaultRefDerefTraits<WTF::SingleThreadWeakPtrImpl> >(WTF::RefPtr<WTF::SingleThreadWeakPtrImpl, WTF::RawPtrTraits<WTF::SingleThreadWeakPtrImpl>, WTF::DefaultRefDerefTraits<WTF::SingleThreadWeakPtrImpl> >&) (o=<synthetic pointer>..., this=0x7f4e9e022120) at /home/fred/src-obj/WebKit/WebKitBuild/RelWithDebInfo/WTF/Headers/wtf/RefPtr.h:189 #3 WTF::RefPtr<WTF::SingleThreadWeakPtrImpl, WTF::RawPtrTraits<WTF::SingleThreadWeakPtrImpl>, WTF::DefaultRefDerefTraits<WTF::SingleThreadWeakPtrImpl> >::operator=(WTF::RefPtr<WTF::SingleThreadWeakPtrImpl, WTF::RawPtrTraits<WTF::SingleThreadWeakPtrImpl>, WTF::DefaultRefDerefTraits<WTF::SingleThreadWeakPtrImpl> >&&) (o=<optimized out>, this=0x7f4e9e022120) at /home/fred/src-obj/WebKit/WebKitBuild/RelWithDebInfo/WTF/Headers/wtf/RefPtr.h:163 #4 WTF::WeakPtr<WebCore::RenderElement, WTF::SingleThreadWeakPtrImpl, WTF::RawPtrTraits<WTF::SingleThreadWeakPtrImpl> >::operator=(WTF::WeakPtr<WebCore::RenderElement, WTF::SingleThreadWeakPtrImpl, WTF::RawPtrTraits<WTF::SingleThreadWeakPtrImpl> >&&) (this=0x7f4e9e022120) at /home/fred/src-obj/WebKit/WebKitBuild/RelWithDebInfo/WTF/Headers/wtf/WeakPtr.h:41 #5 WebCore::RenderObject::setParent(WebCore::RenderElement*) (this=0x7f4e9e022100, parent=<optimized out>) at /home/fred/src-obj/WebKit/Source/WebCore/rendering/RenderObject.cpp:331 #6 0x00007f4f270cc68f in WebCore::RenderElement::attachRendererInternal(std::unique_ptr<WebCore::RenderObject, WebCore::RenderObjectDeleter>, WebCore::RenderObject*) (this=this@entry=0x7f4e9e00f380, child=std::unique_ptr<WebCore::RenderObject> = {...}, beforeChild=0x7f4e9e0007a0) at /usr/include/c++/11/bits/unique_ptr.h:173 #7 0x00007f4f2730298c in WebCore::RenderTreeBuilder::attachToRenderElementInternal(WebCore::RenderElement&, std::unique_ptr<WebCore::RenderObject, WebCore::RenderObjectDeleter>, WebCore::RenderObject*, WebCore::RenderObject::IsInternalMove) (this=this@entry=0x7ffcdfc2e7e0, parent=..., child=std::unique_ptr<WebCore::RenderObject> = {...}, beforeChild=<optimized out>, beforeChild@entry=0x7f4e9e00f560, isInternalMove=isInternalMove@entry=WebCore::RenderObject::IsInternalMove::No) at /usr/include/c++/11/bits/unique_ptr.h:172 #8 0x00007f4f2730a45b in WebCore::RenderTreeBuilder::attachToRenderElementInternal(WebCore::RenderElement&, std::unique_ptr<WebCore::RenderObject, WebCore::RenderObjectDeleter>, WebCore::RenderObject*, WebCore::RenderObject::IsInternalMove) (isInternalMove=WebCore::RenderObject::IsInternalMove::No, beforeChild=0x7f4e9e00f560, child=std::unique_ptr<WebCore::RenderObject> = {...}, parent=..., this=0x7ffcdfc2e7e0) at /home/fred/src-obj/WebKit/Source/WebCore/rendering/updating/RenderTreeBuilder.cpp:402 #9 WebCore::RenderTreeBuilder::attachToRenderElement(WebCore::RenderElement&, std::unique_ptr<WebCore::RenderObject, WebCore::RenderObjectDeleter>, WebCore::RenderObject*) (this=0x7ffcdfc2e7e0, parent=..., child=std::unique_ptr<WebCore::RenderObject> = {...}, beforeChild=beforeChild@entry=0x7f4e9e00f560) at /home/fred/src-obj/WebKit/Source/WebCore/rendering/updating/RenderTreeBuilder.cpp:396 #10 0x00007f4f2731631e in WebCore::RenderTreeBuilder::Inline::attachIgnoringContinuation(WebCore::RenderInline&, std::unique_ptr<WebCore::RenderObject, WebCore::RenderObjectDeleter>, WebCore::RenderObject*) (this=<optimized out>, parent=..., child=std::unique_ptr<WebCore::RenderObject> = {...}, beforeChild=0x7f4e9e00f560) at /usr/include/c++/11/bits/unique_ptr.h:172 #11 0x00007f4f27316725 in WebCore::RenderTreeBuilder::Inline::attach(WebCore::RenderInline&, std::unique_ptr<WebCore::RenderObject, WebCore::RenderObjectDeleter>, WebCore::RenderObject*) (this=0x7f4f055341f0, parent=..., child=std::unique_ptr<WebCore::RenderObject> = {...}, beforeChild=<optimized out>) at /usr/include/c++/11/tuple:454 #12 0x00007f4f27318933 in WebCore::RenderTreeBuilder::Ruby::findOrCreateParentForStyleBasedRubyChild(WebCore::RenderElement&, WebCore::RenderObject const&, WebCore::RenderObject*&) (this=<optimized out>, parent=..., child=<optimized out>, beforeChild=@0x7ffcdfc2bdb8: 0x7f4e9e00f560) at /home/fred/src-obj/WebKit/Source/WebCore/rendering/updating/RenderTreeBuilderRuby.cpp:100 #13 0x00007f4f2730a0c4 in WebCore::RenderTreeBuilder::attachInternal(WebCore::RenderElement&, std::unique_ptr<WebCore::RenderObject, WebCore::RenderObjectDeleter>, WebCore::RenderObject*) (this=0x7ffcdfc2e7e0, parent=..., child=std::unique_ptr<WebCore::RenderObject> = {...}, beforeChild=<optimized out>) at /usr/include/c++/11/bits/unique_ptr.h:173 #14 0x00007f4f2730a55b in operator()(WebCore::RenderElement&) const (__closure=0x7ffcdfc2be80, parentCandidate=...) at /home/fred/src-obj/WebKit/Source/WebCore/rendering/updating/RenderTreeBuilder.cpp:204 #15 0x00007f4f27309cb1 in WebCore::RenderTreeBuilder::attachInternal(WebCore::RenderElement&, std::unique_ptr<WebCore::RenderObject, WebCore::RenderObjectDeleter>, WebCore::RenderObject*) (this=this@entry=0x7ffcdfc2e7e0, parent=..., child=std::unique_ptr<WebCore::RenderObject> = {...}, beforeChild=<optimized out>, beforeChild@entry=0x7f4e9e00f560) at /home/fred/src-obj/WebKit/Source/WebCore/rendering/updating/RenderTreeBuilder.cpp:310 #16 0x00007f4f2730a206 in WebCore::RenderTreeBuilder::attach(WebCore::RenderElement&, std::unique_ptr<WebCore::RenderObject, WebCore::RenderObjectDeleter>, WebCore::RenderObject*) (this=this@entry=0x7ffcdfc2e7e0, parent=..., child=std::unique_ptr<WebCore::RenderObject> = {...}, beforeChild=0x7f4e9e00f560) at /usr/include/c++/11/bits/unique_ptr.h:172 #17 0x00007f4f273220c8 in WebCore::RenderTreeUpdater::createTextRenderer(WebCore::Text&, WebCore::Style::TextUpdate const*) (this=this@entry=0x7ffcdfc2e7b0, textNode=..., textUpdate=textUpdate@entry=0x7f4f055f84f8) at /home/fred/src-obj/WebKit/Source/WebCore/rendering/updating/RenderTreePosition.h:45 #18 0x00007f4f273224ab in WebCore::RenderTreeUpdater::updateTextRenderer(WebCore::Text&, WebCore::Style::TextUpdate const*) (this=this@entry=0x7ffcdfc2e7b0, text=..., textUpdate=textUpdate@entry=0x7f4f055f84f8) at /home/fred/src-obj/WebKit/Source/WebCore/rendering/updating/RenderTreeUpdater.cpp:624 #19 0x00007f4f27322c3e in WebCore::RenderTreeUpdater::updateRenderTree(WebCore::ContainerNode&) (this=this@entry=0x7ffcdfc2e7b0, root=<optimized out>) at /home/fred/src-obj/WebKit/Source/WebCore/rendering/updating/RenderTreeUpdater.cpp:238 #20 0x00007f4f2732306b in WebCore::RenderTreeUpdater::commit(std::unique_ptr<WebCore::Style::Update, std::default_delete<WebCore::Style::Update> >) (this=0x7ffcdfc2e7b0, styleUpdate=std::unique_ptr<WebCore::Style::Update> = {...}) at /home/fred/src-obj/WebKit/Source/WebCore/rendering/updating/RenderTreeUpdater.cpp:127 #21 0x00007f4f26386411 in WebCore::Document::updateRenderTree(std::unique_ptr<WebCore::Style::Update, std::default_delete<WebCore::Style::Update> >) (this=this@entry=0x7f4ead141c00, styleUpdate=std::unique_ptr<WebCore::Style::Update> = {...}) at /usr/include/c++/11/bits/unique_ptr.h:172 #22 0x00007f4f263bafce in WebCore::Document::resolveStyle(WebCore::Document::ResolveStyleType) (this=this@entry=0x7f4ead141c00, type=<optimized out>, type@entry=WebCore::Document::ResolveStyleType::Normal) at /usr/include/c++/11/bits/unique_ptr.h:172 #23 0x00007f4f263bb475 in WebCore::Document::updateStyleIfNeeded() (this=this@entry=0x7f4ead141c00) at /home/fred/src-obj/WebKit/Source/WebCore/dom/Document.cpp:2685 #24 0x00007f4f263bb5a3 in WebCore::Document::updateLayout(WTF::OptionSet<WebCore::LayoutOptions>, WebCore::Element const*) (this=0x7f4ead141c00, layoutOptions=..., context=context@entry=0x0) at /home/fred/src-obj/WebKit/Source/WebCore/dom/Document.cpp:2729 #25 0x00007f4f263bc21c in WebCore::Document::updateLayoutIgnorePendingStylesheets(WTF::OptionSet<WebCore::LayoutOptions>, WebCore::Element const*) (this=<optimized out>, layoutOptions=..., layoutOptions@entry=..., context=context@entry=0x0) at /home/fred/src-obj/WebKit/Source/WebCore/dom/Document.cpp:2692 #26 0x00007f4f26b297bc in WebCore::LocalDOMWindow::scrollTo(WebCore::ScrollToOptions const&, WebCore::ScrollClamping, WebCore::ScrollSnapPointSelectionMethod, std::optional<WebCore::FloatSize>) const (this=this@entry=0x7f4e9e003d90, options=..., clamping=clamping@entry=WebCore::ScrollClamping::Clamped, snapPointSelectionMethod=snapPointSelectionMethod@entry=WebCore::ScrollSnapPointSelectionMethod::Closest, originalScrollDelta=std::optional<WebCore::FloatSize> [no contained value]) at /home/fred/src-obj/WebKit/WebKitBuild/RelWithDebInfo/WTF/Headers/wtf/OptionSet.h:85 attachToRenderElementInternal is called with the following bad configuration: (rr) reverse-finish ... RUBY RenderBlock at (648,2920) size 34x2960 renderer (0x7f4e9e010110) layout box ((nil)) node (0x7f4e9e00d120) layout->[self][normal child] [parent] ---------> RenderInline renderer (0x7f4e9e00f380) layout box ((nil)) layout->[normal child] RenderInline renderer (0x7f4e9e00f420) layout box ((nil)) layout->[normal child] CAPTION RenderInline renderer (0x7f4e9e00f2e0) layout box ((nil)) node (0x7f4e9e00d650) continuation->(0x7f4e9e021b70) layout->[self][normal child] #text RenderText renderer (0x7f4e9e00f5d0) layout box ((nil)) node (0x7f4e9e00d4d0) length->(2) "\n\n" layout->[self] #text RenderText renderer (0x7f4e9e00ec70) layout box ((nil)) node (0x7f4e9e00c400) length->(5) "AAAA\n" layout->[self] [beforeChild]-----> #text RenderText renderer (0x7f4e9e00f560) layout box ((nil)) node (0x7f4e9e00d3b0) length->(1) "\n" layout->[self] Going further up, the inserted child is actually an anonymous rubyBase created by findOrCreateParentForStyleBasedRubyChild. (rr) reverse-finish ... (rr) p showRenderTree(rubyBase.get()) I---YG----- --* RenderInline renderer (0x7f4e9e022100) layout box ((nil)) Going even further up, this is happening in RenderTreeBuilder::attachInternal for the following case: if (parent.style().display() == DisplayType::Ruby || parent.style().display() == DisplayType::RubyBlock) { auto& parentCandidate = rubyBuilder().findOrCreateParentForStyleBasedRubyChild(parent, *child, beforeChild); if (&parentCandidate == &parent) { rubyBuilder().attachForStyleBasedRuby(parentCandidate, WTFMove(child), beforeChild); return; } insertRecursiveIfNeeded(parentCandidate); return; } The parent is a RubyBlock and findOrCreateParentForStyleBasedRubyChild returns the first child as the parentCandidate.
Frédéric Wang (:fredw)
Comment 8
2024-03-22 11:43:23 PDT
(In reply to Rob Buis from
comment #1
)
> Minimized testcase: > <script> > function main() { > document.caretRangeFromPoint().insertNode(caption); > } > </script> > <body onload="main()"> > <ruby style="position: absolute"> > <table> > <caption id="caption"> > <ol></ol> > </caption> > </table> > </ruby> > </body>
That reduced testcase does not crash for me, it only asserts. (In reply to Claudio Saavedra from
comment #3
)
> Created
attachment 470346
[details]
> Reduced test case > > Reduced test case that causes release and debug crashes.
For this one, I'm getting a different backtrace compared to
attachment 469728
[details]
. Trying to reverse-debug what went wrong, we are again reaching a point where attachToRenderElementInternal is called with a bad setup in a RubyBlock subtree (here parent==beforeChild): RUBY RenderBlock at (0,0) size 0x0 renderer (0x7fea01003200) layout box ((nil)) node (0x7fea01004620) layout->[self][normal child] [parent==beforeChild]-->#text RenderText renderer (0x7fea010060f0) layout box ((nil)) node (0x7fea01005d40) length->(13) "AAAA\n " layout->[self] #text RenderText renderer (0x7fea01006430) layout box ((nil)) node (0x7fea01004850) length->(13) "\n " layout->[self] TABLE RenderTable at (0,0) size 0x0 renderer (0x7fea01006510) layout box ((nil)) node (0x7fea01004910) layout->[self] #text RenderText renderer (0x7fea010064a0) layout box ((nil)) node (0x7fea01004db0) length->(7) "\n \n\n" layout->[self] (rr) bt #0 0x00007fea7e0255ce in WebCore::RenderStyle::effectiveContainment() const (this=0x7fea01006140) at /home/fred/src-obj/WebKit/Source/WebCore/rendering/style/RenderStyleInlines.h:199 #1 WebCore::RenderStyle::containsLayout() const (this=0x7fea01006140) at /home/fred/src-obj/WebKit/Source/WebCore/rendering/style/RenderStyleInlines.h:187 #2 WebCore::RenderElement::shouldApplyLayoutContainment() const (this=0x7fea010060f0) at /home/fred/src-obj/WebKit/Source/WebCore/rendering/RenderElementInlines.h:83 #3 WebCore::objectIsRelayoutBoundary (object=0x7fea010060f0) at /home/fred/src-obj/WebKit/Source/WebCore/rendering/RenderObject.cpp:531 #4 WebCore::RenderObject::markContainingBlocksForLayout(WebCore::ScheduleRelayout, WebCore::RenderElement*) (this=this@entry=0x7fea01006680, scheduleRelayout=scheduleRelayout@entry=WebCore::ScheduleRelayout::Yes, newRoot=newRoot@entry=0x0) at /home/fred/src-obj/WebKit/Source/WebCore/rendering/RenderObject.cpp:626 #5 0x00007fea7e19da2d in WebCore::RenderObject::setNeedsLayout(WebCore::MarkingBehavior) (markParents=WebCore::MarkContainingBlockChain, this=0x7fea01006680) at /home/fred/src-obj/WebKit/Source/WebCore/rendering/RenderObject.h:1366 #6 WebCore::RenderObject::setNeedsLayoutAndPrefWidthsRecalc() (this=0x7fea01006680) at /home/fred/src-obj/WebKit/Source/WebCore/rendering/RenderObject.h:1458 #7 WebCore::RenderTreeBuilder::attachToRenderElementInternal(WebCore::RenderElement&, std::unique_ptr<WebCore::RenderObject, WebCore::RenderObjectDeleter>, WebCore::RenderObject*, WebCore::RenderObject::IsInternalMove) (this=this@entry=0x7ffccc45d400, parent=..., child=std::unique_ptr<WebCore::RenderObject> = {...}, beforeChild=<optimized out>, beforeChild@entry=0x7fea010060f0, isInternalMove=isInternalMove@entry=WebCore::RenderObject::IsInternalMove::No) at /home/fred/src-obj/WebKit/Source/WebCore/rendering/updating/RenderTreeBuilder.cpp:427 #8 0x00007fea7e1a545b in WebCore::RenderTreeBuilder::attachToRenderElementInternal(WebCore::RenderElement&, std::unique_ptr<WebCore::RenderObject, WebCore::RenderObjectDeleter>, WebCore::RenderObject*, WebCore::RenderObject::IsInternalMove) (isInternalMove=WebCore::RenderObject::IsInternalMove::No, beforeChild=0x7fea010060f0, child=std::unique_ptr<WebCore::RenderObject> = {...}, parent=..., this=0x7ffccc45d400) at /home/fred/src-obj/WebKit/Source/WebCore/rendering/updating/RenderTreeBuilder.cpp:402 #9 WebCore::RenderTreeBuilder::attachToRenderElement(WebCore::RenderElement&, std::unique_ptr<WebCore::RenderObject, WebCore::RenderObjectDeleter>, WebCore::RenderObject*) (this=this@entry=0x7ffccc45d400, parent=..., child=std::unique_ptr<WebCore::RenderObject> = {...}, beforeChild=0x7fea010060f0) at /home/fred/src-obj/WebKit/Source/WebCore/rendering/updating/RenderTreeBuilder.cpp:396 #10 0x00007fea7e1a5196 in WebCore::RenderTreeBuilder::attachInternal(WebCore::RenderElement&, std::unique_ptr<WebCore::RenderObject, WebCore::RenderObjectDeleter>, WebCore::RenderObject*) (this=0x7ffccc45d400, parent=..., child=std::unique_ptr<WebCore::RenderObject> = {...}, beforeChild=<optimized out>) at /usr/include/c++/11/bits/unique_ptr.h:172 #11 0x00007fea7e1a555b in operator()(WebCore::RenderElement&) const (__closure=0x7ffccc45aa10, parentCandidate=...) at /home/fred/src-obj/WebKit/Source/WebCore/rendering/updating/RenderTreeBuilder.cpp:204 #12 0x00007fea7e1a4cb1 in WebCore::RenderTreeBuilder::attachInternal(WebCore::RenderElement&, std::unique_ptr<WebCore::RenderObject, WebCore::RenderObjectDeleter>, WebCore::RenderObject*) (this=this@entry=0x7ffccc45d400, parent=..., child=std::unique_ptr<WebCore::RenderObject> = {...}, beforeChild=<optimized out>, beforeChild@entry=0x7fea010060f0) at /home/fred/src-obj/WebKit/Source/WebCore/rendering/updating/RenderTreeBuilder.cpp:310 #13 0x00007fea7e1a5206 in WebCore::RenderTreeBuilder::attach(WebCore::RenderElement&, std::unique_ptr<WebCore::RenderObject, WebCore::RenderObjectDeleter>, WebCore::RenderObject*) (this=0x7ffccc45d400, parent=..., child=std::unique_ptr<WebCore::RenderObject> = {...}, beforeChild=0x7fea010060f0) at /usr/include/c++/11/bits/unique_ptr.h:172 #14 0x00007fea7e1bb7b7 in WebCore::RenderTreeUpdater::createRenderer(WebCore::Element&, WebCore::RenderStyle&&) (this=this@entry=0x7ffccc45d3d0, element=..., style=...) at /home/fred/src-obj/WebKit/Source/WebCore/rendering/updating/RenderTreePosition.h:45 #15 0x00007fea7e1bbd49 in WebCore::RenderTreeUpdater::updateElementRenderer(WebCore::Element&, WebCore::Style::ElementUpdate const&) (this=this@entry=0x7ffccc45d3d0, element=..., elementUpdate=...) at /home/fred/src-obj/WebKit/Source/WebCore/rendering/updating/RenderTreeUpdater.cpp:458 #16 0x00007fea7e1bdce1 in WebCore::RenderTreeUpdater::updateRenderTree(WebCore::ContainerNode&) (this=this@entry=0x7ffccc45d3d0, root=<optimized out>) at /home/fred/src-obj/WebKit/Source/WebCore/rendering/updating/RenderTreeUpdater.cpp:262 #17 0x00007fea7e1be09b in WebCore::RenderTreeUpdater::commit(std::unique_ptr<WebCore::Style::Update, std::default_delete<WebCore::Style::Update> >) (this=0x7ffccc45d3d0, styleUpdate=std::unique_ptr<WebCore::Style::Update> = {...}) at /home/fred/src-obj/WebKit/Source/WebCore/rendering/updating/RenderTreeUpdater.cpp:127 #18 0x00007fea7d221411 in WebCore::Document::updateRenderTree(std::unique_ptr<WebCore::Style::Update, std::default_delete<WebCore::Style::Update> >) (this=this@entry=0x7fea58141c00, styleUpdate=std::unique_ptr<WebCore::Style::Update> = {...}) at /usr/include/c++/11/bits/unique_ptr.h:172 #19 0x00007fea7d255fce in WebCore::Document::resolveStyle(WebCore::Document::ResolveStyleType) (this=this@entry=0x7fea58141c00, type=<optimized out>, type@entry=WebCore::Document::ResolveStyleType::Normal) at /usr/include/c++/11/bits/unique_ptr.h:172 #20 0x00007fea7d256475 in WebCore::Document::updateStyleIfNeeded() (this=this@entry=0x7fea58141c00) at /home/fred/src-obj/WebKit/Source/WebCore/dom/Document.cpp:2685 #21 0x00007fea7d25f354 in WebCore::Document::implicitClose() (this=this@entry=0x7fea58141c00) at /home/fred/src-obj/WebKit/Source/WebCore/dom/Document.cpp:3805
Frédéric Wang (:fredw)
Comment 9
2024-03-22 11:55:55 PDT
Created
attachment 470515
[details]
Minimized testcase (similar to original release backtrace) Attached is a reduction of
attachment 469728
[details]
that causes a release crash similar to what is described in
comment 7
and
bug 268768 comment 2
(see backtrace below). destroyAndCleanUpAnonymousWrappers is called with a detached subtree and this happened when inserting the rubyBase created in findOrCreateParentForStyleBasedRubyChild via attachToRenderElementInternal, using the following bad configuration. Note that this testcase relies on some "valid" ruby/rb/rt/rp DOM tree but the render tree is still somewhat broken. Additionally, it involves no DOM mutations, only style changes. RUBY RenderBlock at (8,8) size 92x36 renderer (0x7f524a003200) layout box ((nil)) node (0x7f524a004620) layout->[self][normal child] [parent]------->RenderInline renderer (0x7f524a0050d0) layout box ((nil)) RenderInline renderer (0x7f524a005170) layout box ((nil)) RB RenderInline renderer (0x7f524a005030) layout box ((nil)) node (0x7f524a004700) continuation->(0x7f524a005630) #text RenderText renderer (0x7f524a005210) layout box ((nil)) node (0x7f524a004850) length->(12) "line-wrapped" #text RenderText renderer (0x7f524a0052f0) layout box ((nil)) node (0x7f524a004a60) length->(3) "\n " #text RenderText renderer (0x7f524a005770) layout box ((nil)) node (0x7f524a004b20) length->(3) "\n " RT RenderBlock at (0,0) size 42x10 renderer (0x7f524a005850) layout box ((nil)) node (0x7f524a004c40) layout->[self][normal child] #text RenderText renderer (0x7f524a0057e0) layout box ((nil)) node (0x7f524a004b80) length->(10) "annotation" layout->[self] #text RenderText renderer (0x7f524a005940) layout box ((nil)) node (0x7f524a004be0) length->(3) "\n " [beforeChild]-->#text RenderText renderer (0x7f524a005a20) layout box ((nil)) node (0x7f524a004d80) length->(1) "\n" RB RenderInline renderer (0x7f524a005630) layout box ((nil)) node (0x7f524a004700) #text RenderText renderer (0x7f524a005280) layout box ((nil)) node (0x7f524a0048b0) length->(5) " base" Thread 1 received signal SIGSEGV, Segmentation fault. operator() (__closure=<optimized out>, __closure=<optimized out>) at /home/fred/src-obj/WebKit/Source/WebCore/rendering/updating/RenderTreeBuilder.cpp:818 818 if (!isAnonymousAndSafeToDelete(destroyRootParent)) (rr) bt #0 operator() (__closure=<optimized out>, __closure=<optimized out>) at /home/fred/src-obj/WebKit/Source/WebCore/rendering/updating/RenderTreeBuilder.cpp:818 #1 WebCore::RenderTreeBuilder::destroyAndCleanUpAnonymousWrappers(WebCore::RenderObject&) (this=0x7fff146cbfe0, rendererToDestroy=...) at /home/fred/src-obj/WebKit/Source/WebCore/rendering/updating/RenderTreeBuilder.cpp:828 #2 0x00007f52dceaea95 in WebCore::RenderTreeUpdater::tearDownTextRenderer(WebCore::Text&, WebCore::RenderTreeBuilder&) (text=..., builder=<optimized out>) at /home/fred/src-obj/WebKit/Source/WebCore/rendering/updating/RenderTreeUpdater.cpp:779 #3 0x00007f52dceb2db3 in WebCore::RenderTreeUpdater::tearDownRenderers(WebCore::Element&, WebCore::RenderTreeUpdater::TeardownType, WebCore::RenderTreeBuilder&) (root=..., teardownType=<optimized out>, builder=...) at /home/fred/src-obj/WebKit/Source/WebCore/rendering/updating/RenderTreeUpdater.cpp:762 #4 0x00007f52dceb4c45 in WebCore::RenderTreeUpdater::updateElementRenderer(WebCore::Element&, WebCore::Style::ElementUpdate const&) (this=this@entry=0x7fff146cbfb0, element=..., elementUpdate=...) at /home/fred/src-obj/WebKit/Source/WebCore/rendering/updating/RenderTreeUpdater.cpp:424 #5 0x00007f52dceb6ce1 in WebCore::RenderTreeUpdater::updateRenderTree(WebCore::ContainerNode&) (this=this@entry=0x7fff146cbfb0, root=<optimized out>) at /home/fred/src-obj/WebKit/Source/WebCore/rendering/updating/RenderTreeUpdater.cpp:262 #6 0x00007f52dceb709b in WebCore::RenderTreeUpdater::commit(std::unique_ptr<WebCore::Style::Update, std::default_delete<WebCore::Style::Update> >) (this=0x7fff146cbfb0, styleUpdate=std::unique_ptr<WebCore::Style::Update> = {...}) at /home/fred/src-obj/WebKit/Source/WebCore/rendering/updating/RenderTreeUpdater.cpp:127 #7 0x00007f52dbf1a411 in WebCore::Document::updateRenderTree(std::unique_ptr<WebCore::Style::Update, std::default_delete<WebCore::Style::Update> >) (this=this@entry=0x7f5262141c00, styleUpdate=std::unique_ptr<WebCore::Style::Update> = {...}) at /usr/include/c++/11/bits/unique_ptr.h:172 #8 0x00007f52dbf4efce in WebCore::Document::resolveStyle(WebCore::Document::ResolveStyleType) (this=this@entry=0x7f5262141c00, type=<optimized out>, type@entry=WebCore::Document::ResolveStyleType::Normal) at /usr/include/c++/11/bits/unique_ptr.h:172 #9 0x00007f52dbf4f475 in WebCore::Document::updateStyleIfNeeded() (this=this@entry=0x7f5262141c00) at /home/fred/src-obj/WebKit/Source/WebCore/dom/Document.cpp:2685 #10 0x00007f52dbf51e4e in WebCore::Document::finishedParsing() (this=0x7f5262141c00) at /home/fred/src-obj/WebKit/Source/WebCore/dom/Document.cpp:7249 #11 0x00007f52dc3322c9 in WebCore::HTMLConstructionSite::finishedParsing() (this=<optimized out>) at /home/fred/src-obj/WebKit/Source/WebCore/html/parser/HTMLConstructionSite.cpp:461 #12 0x00007f52dc3574d9 in WebCore::HTMLTreeBuilder::finished() (this=<optimized out>) at /home/fred/src-obj/WebKit/Source/WebCore/html/parser/HTMLTreeBuilder.cpp:3110 #13 0x00007f52dc33b1d0 in WebCore::HTMLDocumentParser::end() (this=0x7f5262013000) at /usr/include/c++/11/bits/unique_ptr.h:173 #14 WebCore::HTMLDocumentParser::attemptToRunDeferredScriptsAndEnd() (this=<optimized out>) at /home/fred/src-obj/WebKit/Source/WebCore/html/parser/HTMLDocumentParser.cpp:455 #15 WebCore::HTMLDocumentParser::prepareToStopParsing() (this=0x7f5262013000) at /home/fred/src-obj/WebKit/Source/WebCore/html/parser/HTMLDocumentParser.cpp:150 #16 0x00007f52dc54664d in WebCore::DocumentWriter::end() (this=0x7f52620a7860) at /home/fred/src-obj/WebKit/Source/WebCore/loader/DocumentWriter.cpp:351 #17 0x00007f52dc555cce in WebCore::DocumentLoader::finishedLoading() (this=0x7f52620a7800) at /home/fred/src-obj/WebKit/Source/WebCore/loader/DocumentLoader.cpp:504
Frédéric Wang (:fredw)
Comment 10
2024-03-22 12:23:25 PDT
Created
attachment 470517
[details]
Minimized testcase (debug assert) Attached is a minimal testcase for the debug assert. It relies on a "valid" DOM tree for ruby and involves no dynamic changes at all. It features a "bad" render tree previously mentioned: <!DOCTYPE> <ruby style="position: absolute"> <rb><span>line-wrapped<div></div> base</span></rb> <rt>annotation</rt> </ruby> RenderBlock (positioned) {RUBY} at (8,8) size 83x36 RenderBlock (anonymous) at (0,0) size 83x18 RenderInline (generated) at (0,0) size 83x17 RenderInline (generated) at (0,0) size 83x17 RenderInline {RB} at (0,0) size 83x17 RenderInline {SPAN} at (0,0) size 83x17 RenderText {#text} at (0,0) size 83x17 text run at (0,0) width 83: "line-wrapped" RenderText {#text} at (0,0) size 0x0 RenderBlock {RT} at (0,0) size 42x10 RenderText {#text} at (0,0) size 42x10 text run at (0,0) width 42: "annotation" RenderText {#text} at (0,0) size 0x0 RenderBlock (anonymous) at (0,18) size 83x0 RenderBlock {DIV} at (0,0) size 83x0 RenderBlock (anonymous) at (0,18) size 83x18 RenderInline {RB} at (0,0) size 28x17 RenderInline {SPAN} at (0,0) size 28x17 RenderText {#text} at (0,0) size 28x17 text run at (0,0) width 28: "base" Because of the position: absolute, the ruby element is a RubyBlock and generates an inline Ruby container per
https://www.w3.org/TR/css-ruby-1/#block-ruby
Because of the <div>, the <rb> annotation is split into several continuations frames that are direct children of the RubyBlock (not of the Ruby container). As Claudio explained, this is the key point causing unexpected behavior (debug assert and release crashes after further dynamic changes) in the other testcases. It seems line wrapping inside the ruby base can be a valid behavior per
https://www.w3.org/TR/css-ruby-1/#break-within
; we should probably insert an anonymous block inside the ruby base so they don't split into the RubyBlock. Alternatively, maybe for now we can just forbid line wrapping in the base as that seems an edge case that is not supported by other browsers (Chromium seems to implement something under a disabled-by-default flag though). Note that we make the ruby DOM tree less structured in order to cause more troubles (as in previous reductions by Claudio and Rob) for example just something like this: <!DOCTYPE> <ruby style="position: absolute"> <span>line-wrapped<div></div> base</span> <rt>annotation</rt> </ruby> The spec describes some fixup that must be performed (by generating anonymous boxes). We should make sure we perform them. See
https://www.w3.org/TR/css-ruby-1/#box-fixup
especially "3. Wrap misparented inline-level content" for grouping consecutive items into anonymous ruby base. Also note that for ruby annotation we have "7. Suppress line breaks"
https://www.w3.org/TR/css-ruby-1/#anon-gen-unbreak
so we shouldn't have this issue when the forced line break is in an <rt> element (and indeed I was not able to reproduce the assert in that case).
Frédéric Wang (:fredw)
Comment 11
2024-03-26 07:22:48 PDT
For completeness, the backtrace of the debug assert is provided below. The assert is happening because the first child is a display: block created by the forced line break: (rr) p showRenderTree(parent.firstChild()) (B)lock/(I)nline/I(N)line-block, (A)bsolute/Fi(X)ed/(R)elative/Stic(K)y, (F)loating, (O)verflow clip, Anon(Y)mous, (G)enerated, has(L)ayer, hasLayer(S)crollableArea, (C)omposited, Content-visibility:(H)idden/(A)uto, (S)kipped content, (+)Dirty style, (+)Dirty layout B---YGLS--- -+ RenderView at (0,0) size 0x0 renderer (0x7fc19e0002c0) layout box ((nil)) layout->[normal child][positioned child] B-----LS--- -+ HTML RenderBlock at (0,0) size 0x0 renderer (0x7fc19e001580) layout box ((nil)) node (0x7fc19e000e40) layout->[self][normal child] B---------- -+ BODY RenderBody at (0,0) size 0x0 renderer (0x7fc19e001820) layout box ((nil)) node (0x7fc19e001040) layout->[self][normal child] BA----L---- -+ RUBY RenderBlock at (0,0) size 0x0 renderer (0x7fc19e0034c0) layout box ((nil)) node (0x7fc19e0040b0) layout->[self][normal child] B---YG----- -+* RenderBlock at (0,0) size 0x0 renderer (0x7fc19e004e50) layout box ((nil)) layout->[self][normal child] I---YG----- -+ RenderInline renderer (0x7fc19e004940) layout box ((nil)) layout->[self][normal child] I---YG----- -+ RenderInline renderer (0x7fc19e004a40) layout box ((nil)) layout->[self][normal child] I---------- -+ RB RenderInline renderer (0x7fc19e004840) layout box ((nil)) node (0x7fc19e004210) continuation->(0x7fc19e0051f0) layout->[self][normal child] I---------- -+ SPAN RenderInline renderer (0x7fc19e004b40) layout box ((nil)) node (0x7fc19e004310) continuation->(0x7fc19e004d00) layout->[self][normal child] I---------- -+ #text RenderText renderer (0x7fc19e004c40) layout box ((nil)) node (0x7fc19e0041a0) length->(12) "line-wrapped" layout->[self] B---YG----- -+ RenderBlock at (0,0) size 0x0 renderer (0x7fc19e004d00) layout box ((nil)) continuation->(0x7fc19e0050f0) layout->[self][normal child] B---------- -+ DIV RenderBlock at (0,0) size 0x0 renderer (0x7fc19e003760) layout box ((nil)) node (0x7fc19e004410) layout->[self] B---YG----- -+ RenderBlock at (0,0) size 0x0 renderer (0x7fc19e004fa0) layout box ((nil)) layout->[self][normal child] I---------- -+ RB RenderInline renderer (0x7fc19e0051f0) layout box ((nil)) node (0x7fc19e004210) layout->[self][normal child] I---------- -+ SPAN RenderInline renderer (0x7fc19e0050f0) layout box ((nil)) node (0x7fc19e004310) layout->[self][normal child] I---------- -+ #text RenderText renderer (0x7fc19e0052f0) layout box ((nil)) node (0x7fc19e004510) length->(5) " base" layout->[self] (rr) p parent.firstChild()->style().display() $2 = WebCore::DisplayType::Block #0 WTFCrash() () at /home/fred/src-obj/WebKit/Source/WTF/wtf/Assertions.cpp:333 #1 0x00007fc226075411 in WTFCrashWithInfo(int, char const*, char const*, int) () at /home/fred/src-obj/WebKit/WebKitBuild/Debug/WTF/Headers/wtf/Assertions.h:778 #2 0x00007fc22cb1e807 in WebCore::RenderTreeBuilder::Ruby::findOrCreateParentForStyleBasedRubyChild(WebCore::RenderElement&, WebCore::RenderObject const&, WebCore::RenderObject*&) (this=0x7fc20f2172b0, parent=..., child=..., beforeChild=@0x7ffd669cb2a0: 0x0) at /home/fred/src-obj/WebKit/Source/WebCore/rendering/updating/RenderTreeBuilderRuby.cpp:276 #3 0x00007fc22cb0957f in WebCore::RenderTreeBuilder::attachInternal(WebCore::RenderElement&, std::unique_ptr<WebCore::RenderObject, WebCore::RenderObjectDeleter>, WebCore::RenderObject*) (this=0x7ffd669ce020, parent=..., child=std::unique_ptr<WebCore::RenderObject> = {...}, beforeChild=0x0) at /home/fred/src-obj/WebKit/Source/WebCore/rendering/updating/RenderTreeBuilder.cpp:323 #4 0x00007fc22cb087ef in WebCore::RenderTreeBuilder::attach(WebCore::RenderElement&, std::unique_ptr<WebCore::RenderObject, WebCore::RenderObjectDeleter>, WebCore::RenderObject*) (this=0x7ffd669ce020, parent=..., child=std::unique_ptr<WebCore::RenderObject> = {...}, beforeChild=0x0) at /home/fred/src-obj/WebKit/Source/WebCore/rendering/updating/RenderTreeBuilder.cpp:192 #5 0x00007fc22cb248e5 in WebCore::RenderTreeUpdater::createTextRenderer(WebCore::Text&, WebCore::Style::TextUpdate const*) (this=0x7ffd669cdff0, textNode=..., textUpdate=0x0) at /home/fred/src-obj/WebKit/Source/WebCore/rendering/updating/RenderTreeUpdater.cpp:592 #6 0x00007fc22cb24ad2 in WebCore::RenderTreeUpdater::updateTextRenderer(WebCore::Text&, WebCore::Style::TextUpdate const*) (this=0x7ffd669cdff0, text=..., textUpdate=0x0) at /home/fred/src-obj/WebKit/Source/WebCore/rendering/updating/RenderTreeUpdater.cpp:624 #7 0x00007fc22cb22d47 in WebCore::RenderTreeUpdater::updateRenderTree(WebCore::ContainerNode&) (this=0x7ffd669cdff0, root=...) at /home/fred/src-obj/WebKit/Source/WebCore/rendering/updating/RenderTreeUpdater.cpp:238 #8 0x00007fc22cb222ad in WebCore::RenderTreeUpdater::commit(std::unique_ptr<WebCore::Style::Update, std::default_delete<WebCore::Style::Update> >) (this=0x7ffd669cdff0, styleUpdate=std::unique_ptr<WebCore::Style::Update> = {...}) at /home/fred/src-obj/WebKit/Source/WebCore/rendering/updating/RenderTreeUpdater.cpp:127 #9 0x00007fc22ab07189 in WebCore::Document::updateRenderTree(std::unique_ptr<WebCore::Style::Update, std::default_delete<WebCore::Style::Update> >) (this=0x7fc1fd121200, styleUpdate=std::unique_ptr<WebCore::Style::Update> = {...}) at /home/fred/src-obj/WebKit/Source/WebCore/dom/Document.cpp:2468 #10 0x00007fc22ab079f1 in WebCore::Document::resolveStyle(WebCore::Document::ResolveStyleType) (this=0x7fc1fd121200, type=WebCore::Document::ResolveStyleType::Rebuild) at /home/fred/src-obj/WebKit/Source/WebCore/dom/Document.cpp:2566 #11 0x00007fc22ab080f1 in WebCore::Document::updateStyleIfNeeded() (this=0x7fc1fd121200) at /home/fred/src-obj/WebKit/Source/WebCore/dom/Document.cpp:2668 #12 0x00007fc22ab22673 in WebCore::Document::finishedParsing() (this=0x7fc1fd121200) at /home/fred/src-obj/WebKit/Source/WebCore/dom/Document.cpp:7185
Frédéric Wang (:fredw)
Comment 12
2024-03-26 08:43:36 PDT
Trying to find hints from the spec for
attachment 470517
[details]
(
comment 10
), some possible ways to workaround the issue (and probably not aligned with the spec) in the short term would be: A. Stop making the RubyBlock a block container so we would be in the same situation as without position: absolute. B. Introduce some anonymous inline-block inside ruby bases, so that continuations would stay within that anonymous. C. Somehow prevent the split to happen if we detect we are within a RubyBlock? But ideally the long-term solution would be to make sure the spec is fixed and implement whatever is decribed there. Below here some more details of relevant sections from the current version of the spec.
https://drafts.csswg.org/css-ruby/#block-ruby
: This is what is explaining why `<ruby style="position: absolute">` is a block-level box with a generated inline-level ruby container. Then by
https://drafts.csswg.org/css-ruby/#formatting-context
, this block-level box is the containing block for the ruby container and internal ruby boxes, and our implementation will thus attach the continuations as children of that block-level box. Note that without the absolute positioning, the inline <ruby> is split into multiple continuations inside an (ancestor) containing block. Not sure this is the expected behavior, but at least that prevents the asserts/crashes.
https://drafts.csswg.org/css-ruby/#anon-gen-inlinize
: The rationale for that seems to make sure everything inside the ruby formatting context is inline somehow, but that does not help here because the <div> is a child of the <span> which is already inline. It seems the issue shows up even without the <span>, but we haven't tried to check why.
https://drafts.csswg.org/css-ruby/#anon-gen-anon-ruby
: This anonymous box fixup has no effect here since we already have explicit ruby element, which is needed to reproduce the issue.
https://drafts.csswg.org/css-ruby/#anon-gen-bare-inlines
: It's worth noting that the issue initially showed up without an explicit base, but this fixup (which we seems to implement) allows to reduce the problem to the case of an explicit base.
https://drafts.csswg.org/css-ruby/#anon-gen-unbreak
: Note that this is only for ruby annotations, while the testcase involves forced line break in a ruby base. Note that the fixup proposed here seems to suggest that only "segment break" are considered in the spec, not those caused by block-level element such as the <div>. It seems we implement ruby annotations as RenderBlock though, so even though the following case generates continuations they remain contained in the annotation: <ruby style="position: absolute"> <rb>base</rb> <rt><span>annotation with <div>forced</div> line break</span></rt> </ruby>
https://drafts.csswg.org/css-ruby/#anon-gen-anon-containers
: Not sure we do that in our implementation, but that won't help if these containers are inline-level.
https://drafts.csswg.org/css-ruby/#break-within
: This seems to be the most relevant paragraph to handle the testcase but it does not mention forced line breaks at all. So either this is underspecified or it should be interpreted as linebreaking is forbidden. Some basic cases showing we do support some soft or forced breaks in annotation without having to deal with continuations: <ruby style="position: absolute; width: 100px"> <rb style="white-space: normal">1 2 3 4 5 6 7 8 9 10</rb> </ruby> <ruby> <rb style="white-space: pre">1 2 3<br/>5 6 7 8 9 10</rb> </ruby>
https://drafts.csswg.org/css-ruby/#break-between
: This one is for breaking between bases, which does not apply to our test case. For completeness, here is an example where we perform breaks but again no continuations are involved, so the tree structure remains ok: <ruby style="position: absolute; width: 100px"> <rb>base1</rb> <rt>annotation1</rt> <rb>base2</rb> <rt>annotation2</rt> </ruby>
Frédéric Wang (:fredw)
Comment 13
2024-04-02 02:31:39 PDT
Created
attachment 470714
[details]
Release crash / debug assert with inline ruby (In reply to Frédéric Wang (:fredw) from
comment #12
)
> A. Stop making the RubyBlock a block container so we would be in the same > situation as without position: absolute.
This option should probably be excluded, since we have issues with inline ruby too. Here is a minimized testcase which allows to reproduce the same issue as
bug 271903
and
bug 271905
. It involves an inline ruby split into multiple continuations causing RenderTreeBuilder::Ruby::attachForStyleBasedRuby to be called with the following bad configuration. Note that the ruby DOM tree is somehow "valid" but the <div> and some "display: contents" allows to hit that bad configuration. RenderView at (0,0) size 0x0 renderer (0x7f48750007a0) layout box ((nil)) layout->[normal child] HTML RenderBlock at (0,0) size 0x0 renderer (0x7f48750015e0) layout box ((nil)) node (0x7f48750010e0) layout->[self][normal child] BODY RenderBody at (0,0) size 0x0 renderer (0x7f48750017f0) layout box ((nil)) node (0x7f4875001230) layout->[self][normal child] RenderBlock at (0,0) size 0x0 renderer (0x7f4875006f20) layout box ((nil)) layout->[self][normal child] [parent]------------>RUBY RenderInline renderer (0x7f4875005e20) layout box ((nil)) node (0x7f4875004530) continuation->(0x7f48750071a0) layout->[self][normal child] RenderInline renderer (0x7f4875005ec0) layout box ((nil)) layout->[self][normal child] #text RenderText renderer (0x7f4875005db0) layout box ((nil)) node (0x7f48750044d0) length->(3) "\n " layout->[self] #text RenderText renderer (0x7f4875005f60) layout box ((nil)) node (0x7f4875004760) length->(5) "\n " layout->[self] SPAN RenderInline renderer (0x7f4875006ca0) layout box ((nil)) node (0x7f4875004820) continuation->(0x7f4875006e30) layout->[self][normal child] #text RenderText renderer (0x7f4875006af0) layout box ((nil)) node (0x7f48750047c0) length->(13) "line-wrapped " layout->[self] #text RenderText renderer (0x7f48750066f0) layout box ((nil)) node (0x7f4875004ab0) length->(3) "\n " layout->[self] #text RenderText renderer (0x7f4875006760) layout box ((nil)) node (0x7f4875004b10) length->(3) "\n " layout->[self] RenderInline renderer (0x7f4875007320) layout box ((nil)) layout->[self][normal child] #text RenderText renderer (0x7f48750072b0) layout box ((nil)) node (0x7f4875004b70) length->(1) "(" layout->[self] #text RenderText renderer (0x7f4875006840) layout box ((nil)) node (0x7f4875004bd0) length->(3) "\n " layout->[self] RenderBlock at (0,0) size 0x0 renderer (0x7f4875006e30) layout box ((nil)) continuation->(0x7f4875007100) layout->[self][normal child] DIV RenderBlock at (0,0) size 0x0 renderer (0x7f4875006d40) layout box ((nil)) node (0x7f4875004900) layout->[self] RenderBlock at (0,0) size 0x0 renderer (0x7f4875007010) layout box ((nil)) layout->[self][normal child] RUBY RenderInline renderer (0x7f48750071a0) layout box ((nil)) node (0x7f4875004530) continuation->(0x7f4875006540) layout->[self][normal child] SPAN RenderInline renderer (0x7f4875007100) layout box ((nil)) node (0x7f4875004820) layout->[self][normal child] #text RenderText renderer (0x7f4875007240) layout box ((nil)) node (0x7f4875004a50) length->(5) " base" layout->[self] RUBY RenderInline renderer (0x7f4875006540) layout box ((nil)) node (0x7f4875004530) layout->[self][normal child] RenderInline renderer (0x7f4875006b60) layout box ((nil)) layout->[self][normal child] [beforeChild]----------->#text RenderText renderer (0x7f4875006a10) layout box ((nil)) node (0x7f4875004d70) length->(3) "\n " layout->[self] RenderInline renderer (0x7f4875006c00) layout box ((nil)) layout->[self][normal child] #text RenderText renderer (0x7f4875006a80) layout box ((nil)) node (0x7f4875004e30) length->(1) "\n" layout->[self] #text RenderText renderer (0x7f4875005cd0) layout box ((nil)) node (0x7f4875004e90) length->(1) "\n" layout->[self] #text RenderText renderer (0x7f4875005d40) layout box ((nil)) node (0x7f4875005020) length->(1) "\n" layout->[self] In debug mode, this then hit ASSERT(!beforeChild || beforeChild->parent() == &parent); to be hit in RenderTreeBuilder::attachToRenderElementInternal. In release mode, this will crash in WebCore::RenderObject::destroy() when releasing a misparented m_previous: Thread 1 received signal SIGSEGV, Segmentation fault. 0x00007f48e63c2e44 in WTFCrash () at /home/fred/src-obj/WebKit/Source/WTF/wtf/Assertions.cpp:333 333 *(int *)(uintptr_t)0xbbadbeef = 0; (rr) bt #0 0x00007f48e63c2e44 in WTFCrash() () at /home/fred/src-obj/WebKit/Source/WTF/wtf/Assertions.cpp:333 #1 0x00007f48e9d31b8c in WTFCrashWithInfo(int, char const*, char const*, int) () at /home/fred/src-obj/WebKit/WebKitBuild/RelWithDebInfo/WTF/Headers/wtf/Assertions.h:778 #2 WebCore::RenderObject::destroy() (this=0x7f48750007a0) at /home/fred/src-obj/WebKit/Source/WebCore/rendering/RenderObject.cpp:1834 #3 0x00007f48e8f9c003 in WebCore::Document::destroyRenderTree() (this=this@entry=0x7f48c4141c00) at /home/fred/src-obj/WebKit/Source/WebCore/dom/Document.cpp:3116 #4 0x00007f48e8fc6265 in WebCore::Document::willBeRemovedFromFrame() (this=this@entry=0x7f48c4141c00) at /home/fred/src-obj/WebKit/Source/WebCore/dom/Document.cpp:3171 #5 0x00007f48e97075a6 in WebCore::LocalFrame::setView(WTF::RefPtr<WebCore::LocalFrameView, WTF::RawPtrTraits<WebCore::LocalFrameView>, WTF::DefaultRefDerefTraits<WebCore::LocalFrameView> >&&) (this=this@entry=0x7f48c60bc240, view=...) at /home/fred/src-obj/WebKit/Source/WebCore/page/LocalFrame.cpp:264 #6 0x00007f48e9724ceb in WebCore::LocalFrame::createView(WebCore::IntSize const&, std::optional<WebCore::Color> const&, WebCore::IntSize const&, WebCore::IntRect const&, bool, WebCore::ScrollbarMode, bool, WebCore::ScrollbarMode, bool) (this=this@entry=0x7f48c60bc240, viewportSize=..., backgroundColor=std::optional<WebCore::Color> [no contained value], fixedLayoutSize=..., fixedVisibleContentRect=..., useFixedLayout=useFixedLayout@entry=false, horizontalScrollbarMode=WebCore::ScrollbarMode::Auto, horizontalLock=false, verticalScrollbarMode=WebCore::ScrollbarMode::Auto, verticalLock=false) at /home/fred/src-obj/WebKit/Source/WebCore/page/LocalFrame.cpp:928 #7 0x00007f48e7cfaf1f in WebKit::WebLocalFrameLoaderClient::transitionToCommittedForNewPage() (this=0x7f48c6035710) at /home/fred/src-obj/WebKit/Source/WebKit/WebProcess/WebPage/WebPage.h:442 #8 0x00007f48e95d6382 in WebCore::FrameLoader::transitionToCommitted(WebCore::CachedPage*) (this=this@entry=0x7f48c60ec1a0, cachedPage=cachedPage@entry=0x0) at /home/fred/src-obj/WebKit/Source/WebCore/loader/FrameLoader.cpp:2395 #9 0x00007f48e95d653f in WebCore::FrameLoader::transitionToCommitted(WebCore::CachedPage*) (cachedPage=0x0, this=0x7f48c60ec1a0) at /home/fred/src-obj/WebKit/Source/WebCore/loader/FrameLoader.cpp:2314 #10 WebCore::FrameLoader::commitProvisionalLoad() (this=0x7f48c60ec1a0) at /home/fred/src-obj/WebKit/Source/WebCore/loader/FrameLoader.cpp:2199 #11 0x00007f48e95ab747 in WebCore::DocumentLoader::commitIfReady() (this=0x7f48c40ac000) at /home/fred/src-obj/WebKit/Source/WebCore/loader/DocumentLoader.cpp:417 #12 WebCore::DocumentLoader::commitIfReady() (this=0x7f48c40ac000) at /home/fred/src-obj/WebKit/Source/WebCore/loader/DocumentLoader.cpp:413 #13 WebCore::DocumentLoader::finishedLoading() (this=0x7f48c40ac000) at /home/fred/src-obj/WebKit/Source/WebCore/loader/DocumentLoader.cpp:488 #14 0x00007f48e95abcc8 in WebCore::DocumentLoader::maybeLoadEmpty() (this=this@entry=0x7f48c40ac000) at /home/fred/src-obj/WebKit/Source/WebCore/loader/DocumentLoader.cpp:2071 #15 0x00007f48e95af0c0 in WebCore::DocumentLoader::startLoadingMainResource() (this=0x7f48c40ac000) at /home/fred/src-obj/WebKit/Source/WebCore/loader/DocumentLoader.cpp:2132 #16 0x00007f48e95c7036 in operator() (__closure=<optimized out>) at /home/fred/src-obj/WebKit/Source/WebCore/loader/FrameLoader.cpp:3883 #17 WTF::Detail::CallableWrapper<WebCore::FrameLoader::continueLoadAfterNavigationPolicy(const WebCore::ResourceRequest&, WebCore::FormState*, WebCore::NavigationPolicyDecision, WebCore::AllowNavigationToInvalidURL)::<lambda()>, void>::call(void) (this=<optimized out>) at /home/fred/src-obj/WebKit/WebKitBuild/RelWithDebInfo/WTF/Headers/wtf/Function.h:53 #18 0x00007f48e77cae99 in WTF::Function<void ()>::operator()() const (this=<optimized out>) at /home/fred/src-obj/WebKit/WebKitBuild/RelWithDebInfo/WTF/Headers/wtf/Function.h:82 #19 WTF::CompletionHandler<void ()>::operator()() (this=<optimized out>) at /home/fred/src-obj/WebKit/WebKitBuild/RelWithDebInfo/WTF/Headers/wtf/CompletionHandler.h:75 #20 0x00007f48e95d7d6b in WebCore::FrameLoader::continueLoadAfterNavigationPolicy(WebCore::ResourceRequest const&, WebCore::FormState*, WebCore::NavigationPolicyDecision, WebCore::AllowNavigationToInvalidURL) (this=0x7f48c60ec1a0, request=<optimized out>, formState=0x0, navigationPolicyDecision=<optimized out>, allowNavigationToInvalidURL=<optimized out>) at /home/fred/src-obj/WebKit/Source/WebCore/loader/FrameLoader.cpp:3887 #21 0x00007f48e95df9a7 in operator() (navigationPolicyDecision=<optimized out>, formState=<optimized out>, request=<optimized out>, __closure=0x7f48c615f7b8) at /home/fred/src-obj/WebKit/Source/WebCore/loader/FrameLoader.cpp:1773 #22 WTF::Detail::CallableWrapper<WebCore::FrameLoader::loadWithDocumentLoader(WebCore::DocumentLoader*, WebCore::FrameLoadType, WTF::RefPtr<WebCore::FormState>&&, WebCore::AllowNavigationToInvalidURL, WTF::CompletionHandler<void()>&&)::<lambda(const WebCore::ResourceRequest&, WTF::WeakPtr<WebCore::FormState, WTF::DefaultWeakPtrImpl, WTF::RawPtrTraits<WTF::DefaultWeakPtrImpl> >&&, WebCore::NavigationPolicyDecision)>, void, WebCore::ResourceRequest&&, WTF::WeakPtr<WebCore::FormState, WTF::DefaultWeakPtrImpl, WTF::RawPtrTraits<WTF::DefaultWeakPtrImpl> >&&, WebCore::NavigationPolicyDecision>::call(WebCore::ResourceRequest &&, WTF::WeakPtr<WebCore::FormState, WTF::DefaultWeakPtrImpl, WTF::RawPtrTraits<WTF::DefaultWeakPtrImpl> > &&, WebCore::NavigationPolicyDecision) (this=0x7f48c615f7b0, in#0=<optimized out>, in#1=<optimized out>, in#2=<optimized out>) at /home/fred/src-obj/WebKit/WebKitBuild/RelWithDebInfo/WTF/Headers/wtf/Function.h:53 #23 0x00007f48e960cb3c in WTF::Function<void (WebCore::ResourceRequest&&, WTF::WeakPtr<WebCore::FormState, WTF::DefaultWeakPtrImpl, WTF::RawPtrTraits<WTF::DefaultWeakPtrImpl> >&&, WebCore::NavigationPolicyDecision)>::operator()(WebCore::ResourceRequest&&, WTF::WeakPtr<WebCore::FormState, WTF::DefaultWeakPtrImpl, WTF::RawPtrTraits<WTF::DefaultWeakPtrImpl> >&&, WebCore::NavigationPolicyDecision) const (in#2=WebCore::NavigationPolicyDecision::ContinueLoad, in#1=..., in#0=..., this=<optimized out>) at /home/fred/src-obj/WebKit/WebKitBuild/RelWithDebInfo/WTF/Headers/wtf/Function.h:79 #24 WTF::CompletionHandler<void (WebCore::ResourceRequest&&, WTF::WeakPtr<WebCore::FormState, WTF::DefaultWeakPtrImpl, WTF::RawPtrTraits<WTF::DefaultWeakPtrImpl> >&&, WebCore::NavigationPolicyDecision)>::operator()(WebCore::ResourceRequest&&, WTF::WeakPtr<WebCore::FormState, WTF::DefaultWeakPtrImpl, WTF::RawPtrTraits<WTF::DefaultWeakPtrImpl> >&&, WebCore::NavigationPolicyDecision) (in#2=WebCore::NavigationPolicyDecision::ContinueLoad, in#1=..., in#0=..., this=0x7f48c6136e38) at /home/fred/src-obj/WebKit/WebKitBuild/RelWithDebInfo/WTF/Headers/wtf/CompletionHandler.h:75 #25 operator()(WebCore::PolicyAction) (__closure=0x7f48c6136e28, policyAction=<optimized out>) at /home/fred/src-obj/WebKit/Source/WebCore/loader/PolicyChecker.cpp:246 #26 0x00007f48e7d2fc65 in WTF::Function<void (WebCore::PolicyAction)>::operator()(WebCore::PolicyAction) const (in#0=<optimized out>, this=<optimized out>) at /home/fred/src-obj/WebKit/WebKitBuild/RelWithDebInfo/WTF/Headers/wtf/Function.h:79 #27 WTF::CompletionHandler<void (WebCore::PolicyAction)>::operator()(WebCore::PolicyAction) (in#0=<optimized out>, this=0x7ffc6ddc6a78) at /home/fred/src-obj/WebKit/WebKitBuild/RelWithDebInfo/WTF/Headers/wtf/CompletionHandler.h:75 #28 WebKit::WebFrame::didReceivePolicyDecision(unsigned long, WebKit::PolicyDecision&&) (this=<optimized out>, listenerID=<optimized out>, policyDecision=...) at /home/fred/src-obj/WebKit/Source/WebKit/WebProcess/WebPage/WebFrame.cpp:518 #29 0x00007f48e7cebddb in std::__invoke_impl<void, WebKit::WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction(const WebCore::NavigationAction&, const WebCore::ResourceRequest&, const WebCore::ResourceResponse&, WebCore::FormState*, const WTF::String&, uint64_t, std::optional<WebCore::HitTestResult>&&, bool, WebCore::SandboxFlags, WebCore::PolicyDecisionMode, WebCore::FramePolicyFunction&&)::<lambda(WebKit::PolicyDecision&&)>, WebKit::PolicyDecision> (__f=...) at /usr/include/c++/11/bits/invoke.h:60 #30 std::__invoke<WebKit::WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction(const WebCore::NavigationAction&, const WebCore::ResourceRequest&, const WebCore::ResourceResponse&, WebCore::FormState*, const WTF::String&, uint64_t, std::optional<WebCore::HitTestResult>&&, bool, WebCore::SandboxFlags, WebCore::PolicyDecisionMode, WebCore::FramePolicyFunction&&)::<lambda(WebKit::PolicyDecision&&)>, WebKit::PolicyDecision> (__fn=...) at /usr/include/c++/11/bits/invoke.h:96 #31 std::__apply_impl<WebKit::WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction(const WebCore::NavigationAction&, const WebCore::ResourceRequest&, const WebCore::ResourceResponse&, WebCore::FormState*, const WTF::String&, uint64_t, std::optional<WebCore::HitTestResult>&&, bool, WebCore::SandboxFlags, WebCore::PolicyDecisionMode, WebCore::FramePolicyFunction&&)::<lambda(WebKit::PolicyDecision&&)>, std::tuple<WebKit::PolicyDecision>, 0> (__t=..., __f=...) at /usr/include/c++/11/tuple:1854 #32 std::apply<WebKit::WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction(const WebCore::NavigationAction&, const WebCore::ResourceRequest&, const WebCore::ResourceResponse&, WebCore::FormState*, const WTF::String&, uint64_t, std::optional<WebCore::HitTestResult>&&, bool, WebCore::SandboxFlags, WebCore::PolicyDecisionMode, WebCore::FramePolicyFunction&&)::<lambda(WebKit::PolicyDecision&&)>, std::tuple<WebKit::PolicyDecision> > (__t=..., __f=...) at /usr/include/c++/11/tuple:1865 #33 IPC::Connection::callReply<Messages::WebPageProxy::DecidePolicyForNavigationActionAsync, WebKit::WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction(const WebCore::NavigationAction&, const WebCore::ResourceRequest&, const WebCore::ResourceResponse&, WebCore::FormState*, const WTF::String&, uint64_t, std::optional<WebCore::HitTestResult>&&, bool, WebCore::SandboxFlags, WebCore::PolicyDecisionMode, WebCore::FramePolicyFunction&&)::<lambda(WebKit::PolicyDecision&&)> > (completionHandler=..., decoder=<optimized out>) at /home/fred/src-obj/WebKit/Source/WebKit/Platform/IPC/Connection.h:761 #34 operator() (decoder=<optimized out>, __closure=0x7f48c6094328) at /home/fred/src-obj/WebKit/Source/WebKit/Platform/IPC/Connection.h:744 #35 WTF::Detail::CallableWrapper<IPC::Connection::makeAsyncReplyHandler<Messages::WebPageProxy::DecidePolicyForNavigationActionAsync, WebKit::WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction(const WebCore::NavigationAction&, const WebCore::ResourceRequest&, const WebCore::ResourceResponse&, WebCore::FormState*, const WTF::String&, uint64_t, std::optional<WebCore::HitTestResult>&&, bool, WebCore::SandboxFlags, WebCore::PolicyDecisionMode, WebCore::FramePolicyFunction&&)::<lambda(WebKit::PolicyDecision&&)> >(WebKit::WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction(const WebCore::NavigationAction&, const WebCore::ResourceRequest&, const WebCore::ResourceResponse&, WebCore::FormState*, const WTF::String&, uint64_t, std::optional<WebCore::HitTestResult>&&, bool, WebCore::SandboxFlags, WebCore::PolicyDecisionMode, WebCore::FramePolicyFunction&&)::<lambda(WebKit::PolicyDecision&&)>&&, WTF::ThreadLikeAssertion)::<lambda(IPC::Decoder*)>, void, IPC::Decoder*>::call(IPC::Decoder *) (this=0x7f48c6094320, in#0=<optimized out>) at /home/fred/src-obj/WebKit/WebKitBuild/RelWithDebInfo/WTF/Headers/wtf/Function.h:53 #36 0x00007f48e79671d1 in WTF::Function<void (IPC::Decoder*)>::operator()(IPC::Decoder*) const (in#0=0x7f48c6018300, this=<optimized out>) at /home/fred/src-obj/WebKit/WebKitBuild/RelWithDebInfo/WTF/Headers/wtf/Function.h:79 #37 WTF::CompletionHandler<void (IPC::Decoder*)>::operator()(IPC::Decoder*) (in#0=0x7f48c6018300, this=0x7ffc6ddc6c70) at /home/fred/src-obj/WebKit/WebKitBuild/RelWithDebInfo/WTF/Headers/wtf/CompletionHandler.h:75 #38 IPC::Connection::dispatchMessage(IPC::Decoder&) (this=0x7f48c602c340, decoder=...) at /home/fred/src-obj/WebKit/Source/WebKit/Platform/IPC/Connection.cpp:1226 #39 0x00007f48e7967375 in IPC::Connection::dispatchMessage(WTF::UniqueRef<IPC::Decoder>) (this=0x7f48c602c340, message=...) at /home/fred/src-obj/WebKit/Source/WebKit/Platform/IPC/Connection.cpp:1292 #40 0x00007f48e7969190 in IPC::Connection::dispatchMessage(WTF::UniqueRef<IPC::Decoder>) (message=..., this=0x7f48c602c340) at /home/fred/src-obj/WebKit/Source/WebKit/Platform/IPC/Connection.cpp:1249 #41 IPC::Connection::dispatchOneIncomingMessage() (this=0x7f48c602c340) at /home/fred/src-obj/WebKit/Source/WebKit/Platform/IPC/Connection.cpp:1357 #42 0x00007f48e63f44a2 in WTF::Function<void ()>::operator()() const (this=<synthetic pointer>) at /home/fred/src-obj/WebKit/Source/WTF/wtf/Function.h:79 #43 WTF::RunLoop::performWork() (this=0x7f48c60140e0) at /home/fred/src-obj/WebKit/Source/WTF/wtf/RunLoop.cpp:147 #44 0x00007f48e645456d in operator() (userData=<optimized out>, __closure=0x0) at /home/fred/src-obj/WebKit/Source/WTF/wtf/glib/RunLoopGLib.cpp:80 #45 _FUN(gpointer) () at /home/fred/src-obj/WebKit/Source/WTF/wtf/glib/RunLoopGLib.cpp:82 #46 0x00007f48e6454ec3 in operator() (__closure=0x0, userData=0x7f48c60140e0, callback=0x7f48e6454560 <_FUN(gpointer)>, source=0x55e572522520) at /home/fred/src-obj/WebKit/Source/WTF/wtf/glib/RunLoopGLib.cpp:53 #47 _FUN(GSource*, GSourceFunc, gpointer) () at /home/fred/src-obj/WebKit/Source/WTF/wtf/glib/RunLoopGLib.cpp:56 #48 0x00007f48e2c9bc44 in g_main_context_dispatch () at /lib/x86_64-linux-gnu/libglib-2.0.so.0 #49 0x00007f48e2cf1258 in () at /lib/x86_64-linux-gnu/libglib-2.0.so.0 #50 0x00007f48e2c9b2b3 in g_main_loop_run () at /lib/x86_64-linux-gnu/libglib-2.0.so.0 #51 0x00007f48e6455010 in WTF::RunLoop::run() () at /home/fred/src-obj/WebKit/Source/WTF/wtf/glib/RunLoopGLib.cpp:108 #52 0x00007f48e7d84a68 in WebKit::AuxiliaryProcessMainBase<WebKit::WebProcess, true>::run(int, char**) (argc=4, argv=0x7ffc6ddc7048, this=0x7ffc6ddc6ec0) at /home/fred/src-obj/WebKit/Source/WebKit/Shared/AuxiliaryProcessMain.h:72 #53 WebKit::AuxiliaryProcessMainBase<WebKit::WebProcess, true>::run(int, char**) (argv=0x7ffc6ddc7048, argc=4, this=0x7ffc6ddc6ec0) at /home/fred/src-obj/WebKit/Source/WebKit/Shared/AuxiliaryProcessMain.h:59 #54 WebKit::AuxiliaryProcessMain<WebKit::WebProcessMainGtk>(int, char**) (argc=4, argv=0x7ffc6ddc7048) at /home/fred/src-obj/WebKit/Source/WebKit/Shared/AuxiliaryProcessMain.h:98 #55 0x00007f48e6aa9d90 in __libc_start_call_main (main=main@entry=0x55e57153b060 <main(int, char**)>, argc=argc@entry=4, argv=argv@entry=0x7ffc6ddc7048) at ../sysdeps/nptl/libc_start_call_main.h:58 #56 0x00007f48e6aa9e40 in __libc_start_main_impl (main=0x55e57153b060 <main(int, char**)>, argc=4, argv=0x7ffc6ddc7048, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7ffc6ddc7038) at ../csu/libc-start.c:392 #57 0x000055e57153b095 in _start ()
Frédéric Wang (:fredw)
Comment 14
2024-04-02 02:49:21 PDT
Created
attachment 470716
[details]
Patch putting children of ruby bases inside an anonymous inline block (In reply to Frédéric Wang (:fredw) from
comment #12
)
> B. Introduce some anonymous inline-block inside ruby bases, so that > continuations would stay within that anonymous.
Attached was the quick patch we tried during our previous analysis for this approach. The render tree for
attachment 470517
[details]
looks what we want (see below) and it allows to fix release crashes for all the testcases from
bug 268770
,
bug 268768
,
bug 271903
and
bug 271905
. However, it also introduces new debug assertion failures and is not a box fixup behavior described in the spec (see
comment 12
) so we were reluctant to send it for review. RenderBlock (positioned) {RUBY} at (8,8) size 83x40 RenderInline (generated) at (0,0) size 83x17 RenderInline (generated) at (0,0) size 83x17 RenderBlock (generated) at (0,0) size 83x36 RenderBlock (anonymous) at (0,0) size 83x18 RenderInline {RB} at (0,0) size 83x17 RenderInline {SPAN} at (0,0) size 83x17 RenderText {#text} at (0,0) size 83x17 text run at (0,0) width 83: "line-wrapped" RenderBlock (anonymous) at (0,18) size 83x0 RenderBlock {DIV} at (0,0) size 83x0 RenderBlock (anonymous) at (0,18) size 83x18 RenderInline {RB} at (0,0) size 28x17 RenderInline {SPAN} at (0,0) size 28x17 RenderText {#text} at (0,0) size 28x17 text run at (0,0) width 28: "base" RenderText {#text} at (0,0) size 0x0 RenderBlock {RT} at (0,12) size 83x10 RenderText {#text} at (20,0) size 43x10 text run at (20,0) width 43: "annotation" RenderInline (generated) at (0,0) size 0x17 RenderBlock (generated) at (83,36) size 0x0 RenderText {#text} at (0,0) size 0x0
Frédéric Wang (:fredw)
Comment 15
2024-04-02 08:08:57 PDT
Bug 271902
is another duplicate for this (the RubyBlock case) and
attachment 470716
[details]
fixes the release crash.
Frédéric Wang (:fredw)
Comment 16
2024-04-10 04:19:07 PDT
***
Bug 268768
has been marked as a duplicate of this bug. ***
Frédéric Wang (:fredw)
Comment 17
2024-04-10 04:19:19 PDT
***
Bug 271903
has been marked as a duplicate of this bug. ***
Frédéric Wang (:fredw)
Comment 18
2024-04-10 04:19:26 PDT
***
Bug 271905
has been marked as a duplicate of this bug. ***
Frédéric Wang (:fredw)
Comment 19
2024-04-10 04:19:34 PDT
***
Bug 271902
has been marked as a duplicate of this bug. ***
Frédéric Wang (:fredw)
Comment 20
2024-04-10 04:22:22 PDT
Antti commented he would take a look. I'm resetting the assignee to make clear Claudio is not working on this right now. Also marked the other bugs as duplicate as per previous analysis.
Antti Koivisto
Comment 21
2024-05-20 07:37:43 PDT
Pull request:
https://github.com/WebKit/WebKit/pull/28788
EWS
Comment 22
2024-05-20 11:37:22 PDT
Committed
279005@main
(c2f9092d3a8e): <
https://commits.webkit.org/279005@main
> Reviewed commits have been landed. Closing PR #28788 and removing active labels.
Tim Nguyen (:ntim)
Comment 23
2024-11-29 14:17:13 PST
***
Bug 277220
has been marked as a duplicate of this bug. ***
Note
You need to
log in
before you can comment on or make changes to this bug.
Top of Page
Format For Printing
XML
Clone This Bug