forked from WebKit/WebKit
-
Notifications
You must be signed in to change notification settings - Fork 0
Initial attempt at implementing referenceTarget #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
…Tables https://bugs.webkit.org/show_bug.cgi?id=285626 rdar://142475225 Reviewed by Yusuke Suzuki and Justin Michaud. Right now we're using the table's backing store as the boxed callee load location. Tables can grow though so that address could get realloced and thus be stale leading to a UAF. This patch puts the boxed load location into the WasmToJSCallee instead. This doesn't increase the effective size of WasmToJSCalle as it's 40 bytes today so there's an extra 8 bytes from our malloc's atom size. * JSTests/wasm/stress/table-set-to-js-then-grow.js: Added. (from.string_appeared_here.import.as.assert.from.string_appeared_here.let.wat.module.type.ri.func.result.i32.import.string_appeared_here.string_appeared_here.func.foo.result.i32.export.string_appeared_here.func.foo.table.table.0.funcref.func.export.string_appeared_here.param.funcref.result.i32.table.grow.table.ref.null.func.i32.const.1.drop.table.table.i32.const.0.local.0.table.grow.table.ref.null.func.i32.const.10.drop.call_indirect.table.type.ri.i32.const.0.foo): * Source/JavaScriptCore/wasm/WasmCallee.cpp: (JSC::Wasm::WasmToJSCallee::WasmToJSCallee): * Source/JavaScriptCore/wasm/WasmCallee.h: * Source/JavaScriptCore/wasm/WasmTable.cpp: (JSC::Wasm::FuncRefTable::setFunction): * Source/JavaScriptCore/wasm/WasmTable.h: Canonical link: https://commits.webkit.org/288618@main
https://bugs.webkit.org/show_bug.cgi?id=282825 rdar://139502479 Reviewed by David Degazio. This patch adds unbinding for all registers for addCatch and addCatchAll too since they also should not carry any bindings from the other blocks. * JSTests/wasm/stress/wasm-bbq-catch-unbind.js: Added. * Source/JavaScriptCore/wasm/WasmBBQJIT.cpp: (JSC::Wasm::BBQJITImpl::BBQJIT::addCatch): (JSC::Wasm::BBQJITImpl::BBQJIT::addCatchAll): Originally-landed-as: 3972761. rdar://141317483 Canonical link: https://commits.webkit.org/288619@main
…y per ID in the same process https://bugs.webkit.org/show_bug.cgi?id=285630 Reviewed by Timothy Hatcher. A combination of using add instead of set in the constructor, not calling remove in the destructor, and using WeakRef instead of WeakPtr as the map value type caused it to get confused sometimes. I hit a local assertion without this but not with this. Since we now have a nullable type returned and properly call remove, using add is fine instead of set. * Source/WebKit/WebProcess/Extensions/WebExtensionControllerProxy.cpp: (WebKit::webExtensionControllerProxies): (WebKit::WebExtensionControllerProxy::get): (WebKit::WebExtensionControllerProxy::~WebExtensionControllerProxy): Canonical link: https://commits.webkit.org/288620@main
…elevant WPT tests. https://bugs.webkit.org/show_bug.cgi?id=285634 Reviewed by NOBODY (OOPS!). This change adds support for a referenceTarget property on ShadowRoot and ShadowRootInit, and a shadowrootreferencetarget property on Templates. It also adds support code to ensure that the referenceTarget is respected when computing values for internal use, such as creating the accessibility tree. These additions are behind a compile-time flag and a feature flag.
alice
pushed a commit
that referenced
this pull request
Feb 13, 2025
…pector rdar://98891055 https://bugs.webkit.org/show_bug.cgi?id=283092 Reviewed by Ryosuke Niwa and BJ Burg. There currently exists a message WebInspectorUIProxy::OpenLocalInspectorFrontend, which the web process sends to the UI process to show Web Inspector for the current web page. This introduces security risks as a compromised website may find its way to send arbitrary messages to the UI process, opening Web Inspector and weakening the web content sandbox. The reason this message exists is because there are useful ways the web process needs to open Web Inspector with initiative. Normally, Web Inspector is opened via one of the Develop menu's items, which is controlled by the UI process. However, Web Inspector can also be opened without being prompted by the UI process first, in these places: 1. In a web page's context menu, the "Inspect Element" option 2. Inside Web Inspector, if the Debug UI is enabled, on the top right corner, a button to open inspector^2 3. In WebKitTestRunner, via the TestRunner::showWebInspector function This patch makes it so that web process can no longer send a message to a UI process to open Web Inspector. This means web process cannot open Web Inspector at will -- it must be either due to the UI process's demand, or it's in one of the above three cases. More details below. I have tested that this change preserves the above three special cases and does prevent the web page from opening Web Inspector at will. - Cases #1 and #2 can be tested from the UI. - Case #3 can be tested with a WebKit test involving Web Inspector. I ran the test LayoutTests/inspector/console/js-completions.html, where I saw the test crashing without special treatment for this case. - To verify that the web page can't open Web Inspector, I followed the reproduction steps from the Radar and saw Web Inspector no longer opens, and opening the external URL also failed as expected. * Source/WebKit/UIProcess/Inspector/WebInspectorUIProxy.messages.in: * Source/WebKit/UIProcess/Inspector/WebInspectorUIProxy.h: * Source/WebKit/UIProcess/Inspector/WebInspectorUIProxy.cpp: (WebKit::WebInspectorUIProxy::connect): - If the UI process wants to open Web Inspector, it sends a WebInspector::Show command to the web process. This patch makes that command take an async reply, so that the anticipated WebInspectorUIProxy::OpenLocalInspectorFrontend message from the web process can now be delivered through that async reply instead. This ensures that OpenLocalInspectorFrontend can only be done when initiated from the UI process (due to user interaction). (WebKit::WebInspectorUIProxy::markAsUnderTest): (WebKit::WebInspectorUIProxy::openLocalInspectorFrontend): (WebKit::WebInspectorUIProxy::closeFrontendPageAndWindow): - To avoid relying on the web process for potentially sensitive parameters, I reworked and removed the canAttach and underTest arguments from openLocalInspectorFrontend. These two values are now stored and managed in the UI process instead, instead of being passed from the web process all the time. - For canAttach, I noticed that the WebInspectorUIProxyMac::platformCanAttach method already implements the same logic as the web process's WebInspector::canAttachWindow. I filed https://webkit.org/b/283435 as a follow-up to clean up the webProcessCanAttach parameter, the canAttachWindow function in the web process, and potentially the m_attached field too, which all become obsolete due to this change. - I couldn't figure out what the `if (m_attached)` in canAttachWindow check does, and to me it had no effect, as this function is not called while inspector is open. - For underTest, I'm now letting the test runner directly set the flag on the WebInspectorUIProxy, as part of my fix to address case #3 from above. (WebKit::WebInspectorUIProxy::showConsole): (WebKit::WebInspectorUIProxy::showResources): (WebKit::WebInspectorUIProxy::showMainResourceForFrame): (WebKit::WebInspectorUIProxy::togglePageProfiling): - As the web process can longer call OpenLocalInspectorFrontend, call show/connect/openLocalInspectorFrontend here in the UI process instead. (WebKit::WebInspectorUIProxy::requestOpenLocalInspectorFrontend): - To preserve the open inspector^2 button (case #2 from above), we still maintain this message, but we ignore it unless it's for opening inspector^2, thus renaming the message as a request. This is all assuming that the Web Inspector is not a compromised web process, so we allow that message from it to come through. * Source/WebKit/WebProcess/Inspector/WebInspector.messages.in: * Source/WebKit/WebProcess/Inspector/WebInspector.h: * Source/WebKit/WebProcess/Inspector/WebInspector.cpp: (WebKit::WebInspector::show): - The Show message now takes an async reply, which is used to replace sending WebInspectorUIProxy::OpenLocalInspectorFrontend later. (WebKit::WebInspector::showConsole): (WebKit::WebInspector::showResources): (WebKit::WebInspector::showMainResourceForFrame): (WebKit::WebInspector::startPageProfiling): (WebKit::WebInspector::stopPageProfiling): - Calling inspectorController()->show() no longer does anything, since it's now the UI process's job to show Web Inspector first, for these functions to merely switch to the appropriate tabs. * Source/WebKit/WebProcess/Inspector/WebInspector.cpp: (WebKit::WebInspector::openLocalInspectorFrontend): * Source/WebKit/WebProcess/Inspector/WebInspectorClient.cpp: (WebKit::WebInspectorClient::openLocalFrontend): - Adapt to the command's reworked version. - This is maintained to allow the opening of inspector^2 from the web process (case #2 from above). For opening inspector^1, this message will be ignored by the UI process. * Source/WebKit/UIProcess/WebPageProxy.cpp: (WebKit::WebPageProxy::contextMenuItemSelected): - When the "Inspect Element" context menu item is selected (case #1 from above), since the web process may not be privileged to open Web Inspector, handle the showing of inspector here in UI process. * Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp: (WTR::TestRunner::showWebInspector): * Tools/WebKitTestRunner/TestInvocation.cpp: (WTR::TestInvocation::didReceiveMessageFromInjectedBundle): * Source/WebKit/UIProcess/API/C/WKPagePrivate.h: * Source/WebKit/UIProcess/API/C/WKPage.cpp: (WKPageShowWebInspectorForTesting): - Preserve letting the WebKitTestRunner open Web Inspector (case #3 from above). - Adapt to the change that we now also let the UI process know about the underTest flag for case #3, rather than letting UI process rely on the value reported by the web process. * Source/WebKit/WebProcess/InjectedBundle/API/c/WKBundlePage.h: * Source/WebKit/WebProcess/InjectedBundle/API/c/WKBundlePage.cpp: (WKBundlePageShowInspectorForTest): Deleted. - No longer used due to my special fix for case #3. Originally-landed-as: 283286.537@safari-7620-branch (694a9b5). rdar://144667626 Canonical link: https://commits.webkit.org/290260@main
alice
pushed a commit
that referenced
this pull request
Apr 8, 2025
https://bugs.webkit.org/show_bug.cgi?id=290862 <rdar://147215658> Reviewed by Antti Koivisto. "Reusing block" type mutations (see RenderTreeBuilder::Inline::splitFlow) followed by float removal may lead to an unexpected state where we have a float to remove, but we have already destroyed m_floatingObjects, causing us to incorrectly assume that the float no longer belongs here (markSiblingsWithFloatsForLayout) and, therefore, does not need to be removed from sibling blocks (in case it is intrusive). What happens here is: 1. tree mutation makes an anon block reused (pre block) 2. a float is removed from said anon block's subtree At #1 we call removeFloatingObjects() which simply clears and destroys m_floatingObjects on the anon block. Now at #2, when we try to remove this float from sibling block containers by calling RenderBlockFlow::markSiblingsWithFloatsForLayout, and we consult m_floatingObjects to see if there's any float associated with the block and we early return as we had already cleared this set at #1. This patch ensures that when markSiblingsWithFloatsForLayout is called with a valid float, we always try to clean up sibling content. * LayoutTests/fast/block/float-remove-after-block-collapse-crash-expected.txt: Added. * LayoutTests/fast/block/float-remove-after-block-collapse-crash.html: Added. * Source/WebCore/rendering/RenderBlockFlow.cpp: (WebCore::RenderBlockFlow::markSiblingsWithFloatsForLayout): Change for (siblings) for (set items) to for (set items) for (siblings) so that the 'for (siblings)' logic can be moved to a lambda and used when there's a valid incoming float. Canonical link: https://commits.webkit.org/293094@main
alice
pushed a commit
that referenced
this pull request
Apr 8, 2025
…n addFloatsToNewParent https://bugs.webkit.org/show_bug.cgi?id=290898 <rdar://143296265> Reviewed by Antti Koivisto. In this patch 1. we let m_floatingObjects go stale on the skipped root (we already do that for the skipped subtree by not running layout) 2. we descend into skipped subtrees while cleaning up floats even when m_floatingObjects is stale/empty Having up-to-date m_floatingObjects on the skipped root, while stale m_floatingObjects on the skipped subtree can lead to issues when (#1) a previously intrusive float (#2) becomes non-intrusive and (#3) eventually gets deleted prevents us from being able to cleanup m_floatingObjects in skipped subtree(s). at #1 m_floatingObjects is populated with the intrusive float (both skipped root and renderers in skipped subtree) and at #2 since we only run layout on the skipped root, m_floatingObjects gets updated by removing this previously intrusive float (skipped subtree becomes stale) and at #3 we don't descend into the skipped subtree to cleanup m_floatingObjects since the skipped root does not have this float anymore (removed at #2). * Source/WebCore/rendering/RenderBlockFlow.cpp: (WebCore::RenderBlockFlow::markSiblingsWithFloatsForLayout): Canonical link: https://commits.webkit.org/293119@main
alice
pushed a commit
that referenced
this pull request
Jun 2, 2025
https://bugs.webkit.org/show_bug.cgi?id=293470 Reviewed by Antti Koivisto. 1. In WebKit, column spanners are moved out of their original insertion position and get reparented under the column container. 2. "is this renderer inside a skipped subtree" logic consults parent state. Now the parent of a column spanner (#1) may be completely outside of 'c-v: h' tricking us into believing the spanner is not hidden. * LayoutTests/imported/w3c/web-platform-tests/css/css-contain/content-visibility/content-visibility-hidden-with-column-spanner-expected.html: Added. * LayoutTests/imported/w3c/web-platform-tests/css/css-contain/content-visibility/content-visibility-hidden-with-column-spanner-ref.html: Added. * LayoutTests/imported/w3c/web-platform-tests/css/css-contain/content-visibility/content-visibility-hidden-with-column-spanner.html: Added. * Source/WebCore/rendering/RenderBlock.cpp: (WebCore::RenderBlock::paintChild): * Source/WebCore/rendering/RenderBlockFlow.cpp: (WebCore::RenderBlockFlow::layoutBlockChildren): * Source/WebCore/rendering/RenderBox.h: * Source/WebCore/rendering/RenderBoxInlines.h: (WebCore::RenderBox::isColumnSpanner const): * Source/WebCore/rendering/RenderObject.cpp: (WebCore::RenderObject::isSkippedContent const): Canonical link: https://commits.webkit.org/295335@main
alice
pushed a commit
that referenced
this pull request
Jun 2, 2025
https://bugs.webkit.org/show_bug.cgi?id=293337 rdar://151740794 Reviewed by Yijia Huang and Justin Michaud. The current MovHintRemoval's analysis looks weird. We should just do liveness analysis globally and use this information for MovHint removal. 1. "Use" is a node which may exit. When exit happens, we should keep all use of live locals at this bytecode exit location alive. 2. "Def" is MovHint. We kill the locals here. And doing fixpoint analysis and using this information to remove MovHint. Also, pruning Availability in OSRAvailabilityAnalysisPhase via bytecode liveness is wrong: they need to keep live nodes from DFG for example. 0: PutHint @x, PROP(@y) 1: OSR exit point #1 (here, loc0 is not alive) 2: -- Pruning happens -- 3: MovHint @x, loc0 4: OSR exit point #2 (here, loc0 is alive) In this case pruning point will remove (0)'s heap availability since @x is not alive from bytecode at (1), but this is wrong as we need this in (4). In this patch, we remove pruneByLiveness in DFGOSRAvailabilityAnalysisPhase. This pruning should happen by the user of DFGOSRAvailabilityAnalysisPhase instead, and it is already happening (see FTLLowerToB3's pruneByLiveness in exit site, which is right. And ObjectAllocationSinking is pruning with CombinedLiveness, this is right since it also accounts Node's liveness in addition to bytecode's liveness.). Let's just make availability just compute the availability for all things, and then we prune some of unnecessary ones at each use of this information. * Source/JavaScriptCore/dfg/DFGMovHintRemovalPhase.cpp: * Source/JavaScriptCore/dfg/DFGOSRAvailabilityAnalysisPhase.cpp: (JSC::DFG::OSRAvailabilityAnalysisPhase::run): Canonical link: https://commits.webkit.org/295369@main
alice
pushed a commit
that referenced
this pull request
Jun 2, 2025
https://bugs.webkit.org/show_bug.cgi?id=293456 Reviewed by Antti Koivisto. 1. setPreferredLogicalWidthsDirty was introduced at 17615@main modeled after setNeedsLayout 2. As with setNeedsLayout, setPreferredLogicalWidthsDirty has the ability to only mark the current renderer dirty (as opposed to the default behavior of marking ancestors as well) 3. Initially (17615@main) MarkOnlyThis was passed in only on the RenderView (as it has no parent) 4. Later at 17621@main, MarkOnlyThis was used to fix a specific bug where an absolute positioned box with percent padding had incorrect size after viewport resize. Here is what happened there: RenderView RenderBlockFlow (html) RenderBlockFlow (body) RenderBlockFlow (absolute positioned box with % padding) - absolute positioned box uses shrink-to-fit sizing when width is auto. The final width is the combination of its min/max widths and the available space. - % padding is resolved against the containing block's width. Now with viewport resize, where the absolute positioned box's containing block is the RenderView - min/max _content_ values stay the same but - the viewport's new size affects the padding value so the box's final min/max values do change. Min/max values (aka preferred width) are cached on the renderers and we don't recompute them unless PreferredLogicalWidthsDirty bit is set to true (similar to needsLayout bit). We mark renderers dirty in two distinct places: #1 when content/style changes before layout or #2 during layout as we figure we need to invalidate more content In many cases (e.g. resize) in order to evaluate the extent of the damage up front and mark all affected renderers dirty would require a full tree walk, so instead we rely on layout to mark additional renderers dirty as needed. ...which is how we fixed the viewport resize bug in 17621@main. if (RelayoutChildren::Yes && renderer.preferredWidthDependsOnAvailableSpace()) renderer.setPreferredLogicalWidthsDirty(true, MarkOnlyThis) - check during layout if the current renderer's final width depends on the available space - if it does, mark the preferred widths dirty This ensures that by the time we get to computeLogicalWidth() -where we compute the final size of the renderer- preferredLogicalWidths bit is already dirty. It guarantees that we re-compute our min/max values, allowing the new padding value to be incorporated. Now consider a scenario where this positioned box has fixed width (e.g. width: 100px) - we still mark preferred widths dirty (we have to) but - in computeLogicalWidth(), we will not re-compute them as we simply take the fixed width (instead of running the shrink-to-fit logic) - and preferredWidths stays dirty So just because we have a box with preferredWidthDependsOnAvailableSpace(), it does not necessarily mean we run shrink-to-fit sizing and as a result we may not clear the dirty bit. ...and this is where setPreferredLogicalWidthsDirty differs from setNeedsLayout. Whenever we call setNeedsLayout(MarkOnlyThis), it is always followed by a layoutIfNeeded() call, clearing the needsLayout bit, while preferredWidths may remain dirty. While it is crucial that no needsLayout bit is set as returning from layout, preferredWidths bits can stay dirty throughout the entire lifetime of a renderer if they are never used. The reason why having a stuck dirty bit is problematic though, is because we rely on them when marking ancestor chain dirty. The default behavior of both needsLayout and preferredLogicalWidthsDirty is MarkContainingBlockChain (when a renderer changes it's likely that parent changes too). With MarkContainingBlockChain, we climb the ancestor chain and mark containers dirty, unless we find an already dirty container. This performance optimization helps to avoid to walk the ancestor chain every time a renderer is marked dirty, but it also assumes that if a renderer is dirty all its ancestors are dirty as well. So now JS mutates some style and we try to mark our ancestor chain dirty to let our containers know that at the subsequent layout they need to re-compute their min/max values if their sizing relies on them. ...but in setPreferredLogicalWidthsDirty, we bail out too early when we come across this stuck renderer and never mark the parents dirty. So maybe 17621@main should have picked MarkContainingBlockChain and not MarkOnlyThis to fully invalidate the ancestor chain. Before considering that let's take a look at how min/max values are used. In block layout we first visit the parent, compute its width and descend into the children and pass in the parent width as available space. If the parent's width depends on the size of the children (e.g. width: min-content), we simply ask the children for their min/max widths. There's a special "preferred width" codepath in our block layout implementation. This codepath computes min/max widths and caches them on the renderers. Important to note that this happens _before_ running layout on the child renderers. (this may sound like some form of circular dependency, but CSS spec is clear about how to resolve cases where child min/max widths depend on the final size of the parent width) What it means is by the time we run layout on a renderer, the parent may have already "forced" the renderer to re-compute the stale min/max widths. So now imagine we are in the renderer's layout code now and come across this line if (RelayoutChildren::Yes && renderer.preferredWidthDependsOnAvailableSpace()) renderer.setPreferredLogicalWidthsDirty(true, MarkOnlyThis) This makes us to re-compute the min/max values even if they are clean (and this is the result of not being able to effectively run invalidation up front, before layout) With MarkOnlyThis, the worst case scenario (beside the sticky bit bug) is that we may end up running min/max computation twice; first triggered by our parent followed by this line above. However, with MarkContainingBlockChain, we would keep re-computing valid and clean min/max values at every layout on the ancestors as well. (as ancestors would see their dirty min/max values at the next layout the first time and then they would re-compute them, followed by us marking them dirty again and so on) While MarkContainingBlockChain is normally what we do as changing min/max values on the child may affect the ancestors too, it is too late to use it at layout due to block layout's "preferred width first -> layout second" order. The fundamental issue here is that we can't tell if the renderer's min/max values got cleared in the current layout frame by ancestors running preferred with computation on their subtree. If we could, we would either 1, not call renderer.setPreferredLogicalWidthsDirty(true, MarkOnlyThis) at all i.e. min/max values are really really clear, so let's just reuse them 2, or call it by passing in MarkContainingBlockChain (and go with #1 at subsequent layout if applicable) TLDR; While it's okay for preferredWidths to stay dirty across layouts, when a renderer is dirty all its ancestors have to be dirty. Calling setPreferredLogicalWidthsDirty() with MarkOnlyThis during layout is also fine as long as we managed to clear it before finishing layout. Here let's just fix the sticky bit by making sure ancestor chain is always fully marked. - add a rare bit to indicate if we used MarkOnlyThis on this renderer - adjust the "if this renderer dirty its parent must be dirty" logic by consulting the MarkOnlyThis bit. * LayoutTests/fast/dynamic/percent-padding-with-shrink-to-fit-parent-expected.html: Added. * LayoutTests/fast/dynamic/percent-padding-with-shrink-to-fit-parent.html: Added. * Source/WebCore/rendering/RenderObject.cpp: (WebCore::RenderObject::setPreferredLogicalWidthsDirty): (WebCore::RenderObject::invalidateContainerPreferredLogicalWidths): * Source/WebCore/rendering/RenderObject.h: Canonical link: https://commits.webkit.org/295501@main
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
https://bugs.webkit.org/show_bug.cgi?id=285634
Reviewed by NOBODY (OOPS!).
This change adds support for a referenceTarget property on ShadowRoot and ShadowRootInit, and a shadowrootreferencetarget property on Templates. It also adds support code to ensure that the referenceTarget is respected when computing values for internal use, such as creating the accessibility tree.
These additions are behind a compile-time flag and a feature flag.
Additionally, this change imports the relevant WPT tests.