Branch: refs/heads/main
  Home:   https://github.com/WebKit/WebKit
  Commit: f78e2fb7cfb10417c5a99affaba7fcad58226c52
      
https://github.com/WebKit/WebKit/commit/f78e2fb7cfb10417c5a99affaba7fcad58226c52
  Author: Alexey Proskuryakov <[email protected]>
  Date:   2026-08-18 (Tue, 18 Aug 2026)

  Changed paths:
    M Source/WebKit/UIProcess/WebFrameProxy.h
    M Source/WebKit/UIProcess/WebPageProxy.cpp
    M Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp
    M Source/WebKit/WebProcess/WebPage/WebFrame.cpp
    M Source/WebKit/WebProcess/WebPage/WebFrame.h
    M Tools/TestWebKitAPI/Tests/WebKit/WKWebView/Download.mm

  Log Message:
  -----------
  REGRESSION (319105@main): a policy decision that outlives its navigation is 
honored for a load it does not belong to
https://bugs.webkit.org/show_bug.cgi?id=321833
rdar://184974939

Reviewed by Alex Christensen.

A download attribute check outlives the navigation that follows it, which 
319105@main made deliberate. Two
things followed.

The check DocumentLoader::willSendRequest() makes for a redirect reuses the 
navigation's triggering action,
download attribute and all, so it was taken for the download's own check and 
left outstanding when the
navigation was cancelled. Answering it then started a download of the redirect 
target for a navigation that
was already gone. Only the check for the activation is the download's, and it 
is the one made with no
redirect response: PolicyChecker makes no other check that carries a download 
attribute, so the redirect
response tells the two apart, in both processes.

A decision that arrives once a newer navigation owns the load its check was 
made for was applied to that
navigation. The website policies are the clearest of these, disabling content 
JavaScript in a document the
client allowed it for; the navigation identifier and origin keying in the same 
decision belong to the load
that is gone. Record that load with the check, and once it is gone answer 
anything but a download Ignore.

Tests: 
TestWebKitAPI.WKDownload.DownloadAttributeRedirectCheckIsCancelledWithItsNavigation
       
TestWebKitAPI.WKDownload.DownloadAttributeDecisionDoesNotApplyPoliciesToNewerNavigation

* Source/WebKit/UIProcess/WebFrameProxy.h: Say which checks are download checks.
* Source/WebKit/UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::decidePolicyForNavigationAction): Keep a redirect check 
out of them.
* Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp:
(WebKit::WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction): Ditto, 
and record the load the
check is made for.
* Source/WebKit/WebProcess/WebPage/WebFrame.cpp:
(WebKit::WebFrame::setUpPolicyListener): Store it.
(WebKit::WebFrame::newerNavigationOwnsDownloadAttributePolicyCheckLoad): Added.
(WebKit::WebFrame::didReceivePolicyDecision): Answer a decision whose load a 
newer navigation has taken over
Ignore, unless it is a download, which is all that is still meaningful.
* Source/WebKit/WebProcess/WebPage/WebFrame.h: Added the load to PolicyCheck 
and to setUpPolicyListener().
Declared newerNavigationOwnsDownloadAttributePolicyCheckLoad().
* Tools/TestWebKitAPI/Tests/WebKit/WKWebView/Download.mm:
(TEST(WKDownload, DownloadAttributeRedirectCheckIsCancelledWithItsNavigation)): 
Added. Holds the redirect
decision, cancels the navigation, then answers Download, and round trips 
through the server so that a
download started by the answer has been served before the check. No layout 
test: WebKitTestRunner answers
Download for every download attribute action, so it never reaches a redirect in 
one.
(TEST(WKDownload, 
DownloadAttributeDecisionDoesNotApplyPoliciesToNewerNavigation)): Added. 
Answers the newer
navigation first so the download's decision is the last word on the policies of 
a load that is still
provisional, and checks that load's script still runs. The navigation 
identifier in the same decision is not
covered: for a main frame the newer navigation's own decision re-stamps the 
right one immediately, so the
damage does not survive. The sandbox extension is not covered either: only a 
file: URL is granted one, and
swapping which load it belongs to changes nothing observable while the process 
holds read access to the file
by other grants.

Canonical link: https://commits.webkit.org/319378@main



To unsubscribe from these emails, change your notification settings at 
https://github.com/WebKit/WebKit/settings/notifications

Reply via email to