Title: [223413] trunk
Revision
223413
Author
[email protected]
Date
2017-10-16 09:59:47 -0700 (Mon, 16 Oct 2017)

Log Message

Clicks on Link with download attribute causes all (other) links to trigger download when clicked
https://bugs.webkit.org/show_bug.cgi?id=178267
<rdar://problem/34985016>

Reviewed by Darin Adler.

LayoutTests/imported/w3c:

Rebaseline test which behave differently now in WebKit2 due to WKTR's injected bundle
using PassThrough policy for new windows. The new result is identical to what you
would get when you open the test in Safari so I think this is a good thing.

* web-platform-tests/html/browsers/windows/noreferrer-window-name-expected.txt:

Source/WebKit:

When clicking on an anchor with the download attribute, the m_syncNavigationActionHasDownloadAttribute
flag on WebPageProxy would get set. This flag would not get reset right away and instead, it would get
updated during the next call to WebPageProxy::decidePolicyForNavigationAction(). The issue is that if
you later click on a link with target="_blank", WebPageProxy::decidePolicyForNewWindowAction() gets
called instead of WebPageProxy::decidePolicyForNavigationAction() and we do not reset the
m_syncNavigationActionHasDownloadAttribute flag and we force a download.

To address the problem, I got rid of this flag on WebPageProxy and it is error-prone and should really
not be at page-level. Instead, I added a shouldForceDownload flag on the navigation object. It makes
more sense to associate the flag with the navigation and makes it less error-prone.

* UIProcess/API/APINavigation.h:
(API::Navigation::setShouldForceDownload):
(API::Navigation::shouldForceDownload const):
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::receivedPolicyDecision):
(WebKit::WebPageProxy::decidePolicyForNavigationAction):
* UIProcess/WebPageProxy.h:

Tools:

Use PassThrough policy in WKTR's InjectedBundle's decidePolicyForNewWindowAction so that the
request is sent to the UIProcess. This gets WKTR's closer to Safari behavior and helps
reproduce the bug. Without this change, I would not be able to write a regression test for
this bug that is very easily reproducible in Safari.

* WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp:
(WTR::InjectedBundlePage::decidePolicyForNewWindowAction):

LayoutTests:

Add layout test coverage.

* http/tests/download/anchor-load-after-download-expected.txt: Added.
* http/tests/download/anchor-load-after-download.html: Added.
* platform/ios-wk2/TestExpectations:
* platform/mac-wk1/TestExpectations:
* platform/mac-wk1/imported/w3c/web-platform-tests/html/browsers/windows/noreferrer-window-name-expected.txt: Copied from LayoutTests/imported/w3c/web-platform-tests/html/browsers/windows/noreferrer-window-name-expected.txt.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (223412 => 223413)


--- trunk/LayoutTests/ChangeLog	2017-10-16 16:40:48 UTC (rev 223412)
+++ trunk/LayoutTests/ChangeLog	2017-10-16 16:59:47 UTC (rev 223413)
@@ -1,3 +1,19 @@
+2017-10-16  Chris Dumez  <[email protected]>
+
+        Clicks on Link with download attribute causes all (other) links to trigger download when clicked
+        https://bugs.webkit.org/show_bug.cgi?id=178267
+        <rdar://problem/34985016>
+
+        Reviewed by Darin Adler.
+
+        Add layout test coverage.
+
+        * http/tests/download/anchor-load-after-download-expected.txt: Added.
+        * http/tests/download/anchor-load-after-download.html: Added.
+        * platform/ios-wk2/TestExpectations:
+        * platform/mac-wk1/TestExpectations:
+        * platform/mac-wk1/imported/w3c/web-platform-tests/html/browsers/windows/noreferrer-window-name-expected.txt: Copied from LayoutTests/imported/w3c/web-platform-tests/html/browsers/windows/noreferrer-window-name-expected.txt.
+
 2017-10-16  Ryan Haddad  <[email protected]>
 
         Rebaseline imported/w3c/web-platform-tests/beacon/headers/header-content-type.html for macOS.

Added: trunk/LayoutTests/http/tests/download/anchor-load-after-download-expected.txt (0 => 223413)


--- trunk/LayoutTests/http/tests/download/anchor-load-after-download-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/http/tests/download/anchor-load-after-download-expected.txt	2017-10-16 16:59:47 UTC (rev 223413)
@@ -0,0 +1,5 @@
+Clicking the download link link and then the non-download link should not cause a second download.
+
+This test passes if it does not time out.
+
+Link with download attribute. Link without download attribute.

Added: trunk/LayoutTests/http/tests/download/anchor-load-after-download.html (0 => 223413)


--- trunk/LayoutTests/http/tests/download/anchor-load-after-download.html	                        (rev 0)
+++ trunk/LayoutTests/http/tests/download/anchor-load-after-download.html	2017-10-16 16:59:47 UTC (rev 223413)
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script>
+if (window.testRunner) {
+  testRunner.dumpAsText();
+  testRunner.waitUntilDone();
+}
+</script>
+</head>
+<body>
+<p>Clicking the download link link and then the non-download link should not cause a second download.</p>
+<p>This test passes if it does not time out.</p>
+<a id="download-url" href='' download="test.html">Link with download attribute.</a>
+<a id="non-download-url" href="" target="_blank">Link without download attribute.</a>
+<script>
+function runTest()
+{
+    var downloadLink = document.getElementById("download-url");
+    var nonDownloadLink = document.getElementById("non-download-url");
+    downloadLink.click();
+    setTimeout(function() {
+        nonDownloadLink.click();
+    }, 0);
+}
+runTest();
+</script>
+</body>
+</html>

Modified: trunk/LayoutTests/imported/w3c/ChangeLog (223412 => 223413)


--- trunk/LayoutTests/imported/w3c/ChangeLog	2017-10-16 16:40:48 UTC (rev 223412)
+++ trunk/LayoutTests/imported/w3c/ChangeLog	2017-10-16 16:59:47 UTC (rev 223413)
@@ -1,3 +1,17 @@
+2017-10-16  Chris Dumez  <[email protected]>
+
+        Clicks on Link with download attribute causes all (other) links to trigger download when clicked
+        https://bugs.webkit.org/show_bug.cgi?id=178267
+        <rdar://problem/34985016>
+
+        Reviewed by Darin Adler.
+
+        Rebaseline test which behave differently now in WebKit2 due to WKTR's injected bundle
+        using PassThrough policy for new windows. The new result is identical to what you
+        would get when you open the test in Safari so I think this is a good thing.
+
+        * web-platform-tests/html/browsers/windows/noreferrer-window-name-expected.txt:
+
 2017-10-14  Youenn Fablet  <[email protected]>
 
         Resync tests up to c1716b039411090428e7073158b1aea081dafe71

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/html/browsers/windows/noreferrer-window-name-expected.txt (223412 => 223413)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/html/browsers/windows/noreferrer-window-name-expected.txt	2017-10-16 16:40:48 UTC (rev 223412)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/html/browsers/windows/noreferrer-window-name-expected.txt	2017-10-16 16:59:47 UTC (rev 223413)
@@ -1,13 +1,7 @@
-CONSOLE MESSAGE: line 37: Unsafe _javascript_ attempt to initiate navigation for frame with URL '' from frame with URL 'http://localhost:8800/html/browsers/windows/noreferrer-window-name.html'. The frame attempting navigation is neither same-origin with the target, nor is it the target's parent or opener.
 
-CONSOLE MESSAGE: line 38: Unsafe _javascript_ attempt to initiate navigation for frame with URL '' from frame with URL 'http://localhost:8800/html/browsers/windows/noreferrer-window-name.html'. The frame attempting navigation is neither same-origin with the target, nor is it the target's parent or opener.
-
-CONSOLE MESSAGE: line 38: Unsafe _javascript_ attempt to initiate navigation for frame with URL '' from frame with URL 'http://localhost:8800/html/browsers/windows/noreferrer-window-name.html'. The frame attempting navigation is neither same-origin with the target, nor is it the target's parent or opener.
-
-
 Harness Error (TIMEOUT), message = null
 
-PASS Following a noreferrer link with a named target should not cause creation of a window that can be targeted by another noreferrer link with the same named target 
+TIMEOUT Following a noreferrer link with a named target should not cause creation of a window that can be targeted by another noreferrer link with the same named target Test timed out
 PASS Targeting a rel=noreferrer link at an existing named subframe should work 
 TIMEOUT Targeting a rel=noreferrer link at an existing named window should work Test timed out
 

Modified: trunk/LayoutTests/platform/ios-wk2/TestExpectations (223412 => 223413)


--- trunk/LayoutTests/platform/ios-wk2/TestExpectations	2017-10-16 16:40:48 UTC (rev 223412)
+++ trunk/LayoutTests/platform/ios-wk2/TestExpectations	2017-10-16 16:59:47 UTC (rev 223413)
@@ -1816,6 +1816,7 @@
 webkit.org/b/156067 http/tests/download/anchor-download-attribute-content-disposition.html [ Skip ]
 webkit.org/b/156067 http/tests/download/anchor-download-no-extension.html [ Skip ]
 webkit.org/b/156067 http/tests/download/anchor-download-redirect.html [ Skip ]
+webkit.org/b/156067 http/tests/download/anchor-load-after-download.html [ Skip ]
 webkit.org/b/156067 http/tests/download/area-download.html [ Skip ]
 webkit.org/b/156067 http/tests/security/anchor-download-allow-blob.html [ Skip ]
 webkit.org/b/156067 http/tests/security/anchor-download-allow-data.html [ Skip ]

Modified: trunk/LayoutTests/platform/mac-wk1/TestExpectations (223412 => 223413)


--- trunk/LayoutTests/platform/mac-wk1/TestExpectations	2017-10-16 16:40:48 UTC (rev 223412)
+++ trunk/LayoutTests/platform/mac-wk1/TestExpectations	2017-10-16 16:59:47 UTC (rev 223413)
@@ -251,6 +251,7 @@
 webkit.org/b/156069 http/tests/download/anchor-download-attribute-content-disposition.html [ Skip ]
 webkit.org/b/156069 http/tests/download/anchor-download-no-extension.html [ Skip ]
 webkit.org/b/156069 http/tests/download/anchor-download-redirect.html [ Skip ]
+webkit.org/b/156069 http/tests/download/anchor-load-after-download.html [ Skip ]
 webkit.org/b/156069 http/tests/download/area-download.html [ Skip ]
 webkit.org/b/156069 http/tests/security/anchor-download-allow-blob.html [ Skip ]
 webkit.org/b/156069 http/tests/security/anchor-download-allow-data.html [ Skip ]

Copied: trunk/LayoutTests/platform/mac-wk1/imported/w3c/web-platform-tests/html/browsers/windows/noreferrer-window-name-expected.txt (from rev 223412, trunk/LayoutTests/imported/w3c/web-platform-tests/html/browsers/windows/noreferrer-window-name-expected.txt) (0 => 223413)


--- trunk/LayoutTests/platform/mac-wk1/imported/w3c/web-platform-tests/html/browsers/windows/noreferrer-window-name-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/platform/mac-wk1/imported/w3c/web-platform-tests/html/browsers/windows/noreferrer-window-name-expected.txt	2017-10-16 16:59:47 UTC (rev 223413)
@@ -0,0 +1,13 @@
+CONSOLE MESSAGE: line 37: Unsafe _javascript_ attempt to initiate navigation for frame with URL '' from frame with URL 'http://localhost:8800/html/browsers/windows/noreferrer-window-name.html'. The frame attempting navigation is neither same-origin with the target, nor is it the target's parent or opener.
+
+CONSOLE MESSAGE: line 38: Unsafe _javascript_ attempt to initiate navigation for frame with URL '' from frame with URL 'http://localhost:8800/html/browsers/windows/noreferrer-window-name.html'. The frame attempting navigation is neither same-origin with the target, nor is it the target's parent or opener.
+
+CONSOLE MESSAGE: line 38: Unsafe _javascript_ attempt to initiate navigation for frame with URL '' from frame with URL 'http://localhost:8800/html/browsers/windows/noreferrer-window-name.html'. The frame attempting navigation is neither same-origin with the target, nor is it the target's parent or opener.
+
+
+Harness Error (TIMEOUT), message = null
+
+PASS Following a noreferrer link with a named target should not cause creation of a window that can be targeted by another noreferrer link with the same named target 
+PASS Targeting a rel=noreferrer link at an existing named subframe should work 
+TIMEOUT Targeting a rel=noreferrer link at an existing named window should work Test timed out
+

Modified: trunk/Source/WebKit/ChangeLog (223412 => 223413)


--- trunk/Source/WebKit/ChangeLog	2017-10-16 16:40:48 UTC (rev 223412)
+++ trunk/Source/WebKit/ChangeLog	2017-10-16 16:59:47 UTC (rev 223413)
@@ -1,3 +1,30 @@
+2017-10-16  Chris Dumez  <[email protected]>
+
+        Clicks on Link with download attribute causes all (other) links to trigger download when clicked
+        https://bugs.webkit.org/show_bug.cgi?id=178267
+        <rdar://problem/34985016>
+
+        Reviewed by Darin Adler.
+
+        When clicking on an anchor with the download attribute, the m_syncNavigationActionHasDownloadAttribute
+        flag on WebPageProxy would get set. This flag would not get reset right away and instead, it would get
+        updated during the next call to WebPageProxy::decidePolicyForNavigationAction(). The issue is that if
+        you later click on a link with target="_blank", WebPageProxy::decidePolicyForNewWindowAction() gets
+        called instead of WebPageProxy::decidePolicyForNavigationAction() and we do not reset the
+        m_syncNavigationActionHasDownloadAttribute flag and we force a download.
+
+        To address the problem, I got rid of this flag on WebPageProxy and it is error-prone and should really
+        not be at page-level. Instead, I added a shouldForceDownload flag on the navigation object. It makes
+        more sense to associate the flag with the navigation and makes it less error-prone.
+
+        * UIProcess/API/APINavigation.h:
+        (API::Navigation::setShouldForceDownload):
+        (API::Navigation::shouldForceDownload const):
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::receivedPolicyDecision):
+        (WebKit::WebPageProxy::decidePolicyForNavigationAction):
+        * UIProcess/WebPageProxy.h:
+
 2017-10-16  Ryan Haddad  <[email protected]>
 
         Unreviewed, rolling out r223271.

Modified: trunk/Source/WebKit/UIProcess/API/APINavigation.h (223412 => 223413)


--- trunk/Source/WebKit/UIProcess/API/APINavigation.h	2017-10-16 16:40:48 UTC (rev 223412)
+++ trunk/Source/WebKit/UIProcess/API/APINavigation.h	2017-10-16 16:59:47 UTC (rev 223413)
@@ -59,6 +59,9 @@
     void setWasUserInitiated(bool value) { m_wasUserInitiated = value; }
     bool wasUserInitiated() const { return m_wasUserInitiated; }
 
+    void setShouldForceDownload(bool value) { m_shouldForceDownload = value; }
+    bool shouldForceDownload() const { return m_shouldForceDownload; }
+
 private:
     explicit Navigation(WebKit::WebNavigationState&);
     explicit Navigation(WebKit::WebNavigationState&, WebCore::ResourceRequest&&);
@@ -67,6 +70,7 @@
     WebCore::ResourceRequest m_request;
     Vector<WebCore::URL> m_redirectChain;
     bool m_wasUserInitiated { true };
+    bool m_shouldForceDownload { false };
 };
 
 } // namespace API

Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.cpp (223412 => 223413)


--- trunk/Source/WebKit/UIProcess/WebPageProxy.cpp	2017-10-16 16:40:48 UTC (rev 223412)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.cpp	2017-10-16 16:59:47 UTC (rev 223413)
@@ -2285,10 +2285,8 @@
     if (action == PolicyAction::Ignore)
         m_pageLoadState.clearPendingAPIRequestURL(transaction);
 
-#if ENABLE(DOWNLOAD_ATTRIBUTE)
-    if (m_syncNavigationActionHasDownloadAttribute && action == PolicyAction::Use)
+    if (navigation && navigation->shouldForceDownload() && action == PolicyAction::Use)
         action = ""
-#endif
 
     DownloadID downloadID = { };
     if (action == PolicyAction::Download) {
@@ -3695,10 +3693,12 @@
         auto navigation = m_navigationState->createLoadRequestNavigation(ResourceRequest(request));
         newNavigationID = navigation->navigationID();
         navigation->setWasUserInitiated(!!navigationActionData.userGestureTokenIdentifier);
+        navigation->setShouldForceDownload(!navigationActionData.downloadAttribute.isNull());
         listener->setNavigation(WTFMove(navigation));
     } else {
         auto& navigation = m_navigationState->navigation(navigationID);
         navigation.setWasUserInitiated(!!navigationActionData.userGestureTokenIdentifier);
+        navigation.setShouldForceDownload(!navigationActionData.downloadAttribute.isNull());
         listener->setNavigation(navigation);
     }
 
@@ -3714,9 +3714,6 @@
     
     m_inDecidePolicyForNavigationAction = true;
     m_syncNavigationActionPolicyActionIsValid = false;
-#if ENABLE(DOWNLOAD_ATTRIBUTE)
-    m_syncNavigationActionHasDownloadAttribute = !navigationActionData.downloadAttribute.isNull();
-#endif
 
     WebFrameProxy* originatingFrame = m_process->webFrame(originatingFrameInfoData.frameID);
 

Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.h (223412 => 223413)


--- trunk/Source/WebKit/UIProcess/WebPageProxy.h	2017-10-16 16:40:48 UTC (rev 223412)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.h	2017-10-16 16:59:47 UTC (rev 223413)
@@ -2003,10 +2003,6 @@
     bool m_isPointerLocked { false };
 #endif
 
-#if ENABLE(DOWNLOAD_ATTRIBUTE)
-    bool m_syncNavigationActionHasDownloadAttribute { false };
-#endif
-
     bool m_isUsingHighPerformanceWebGL { false };
 
     WeakPtrFactory<WebPageProxy> m_weakPtrFactory;

Modified: trunk/Tools/ChangeLog (223412 => 223413)


--- trunk/Tools/ChangeLog	2017-10-16 16:40:48 UTC (rev 223412)
+++ trunk/Tools/ChangeLog	2017-10-16 16:59:47 UTC (rev 223413)
@@ -1,3 +1,19 @@
+2017-10-16  Chris Dumez  <[email protected]>
+
+        Clicks on Link with download attribute causes all (other) links to trigger download when clicked
+        https://bugs.webkit.org/show_bug.cgi?id=178267
+        <rdar://problem/34985016>
+
+        Reviewed by Darin Adler.
+
+        Use PassThrough policy in WKTR's InjectedBundle's decidePolicyForNewWindowAction so that the
+        request is sent to the UIProcess. This gets WKTR's closer to Safari behavior and helps
+        reproduce the bug. Without this change, I would not be able to write a regression test for
+        this bug that is very easily reproducible in Safari.
+
+        * WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp:
+        (WTR::InjectedBundlePage::decidePolicyForNewWindowAction):
+
 2017-10-16  Emilio Cobos Álvarez  <[email protected]>
 
         Add Emilio Cobos Álvarez to the contributors list.

Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp (223412 => 223413)


--- trunk/Tools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp	2017-10-16 16:40:48 UTC (rev 223412)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp	2017-10-16 16:59:47 UTC (rev 223413)
@@ -1358,7 +1358,7 @@
 
 WKBundlePagePolicyAction InjectedBundlePage::decidePolicyForNewWindowAction(WKBundlePageRef, WKBundleFrameRef, WKBundleNavigationActionRef, WKURLRequestRef, WKStringRef, WKTypeRef*)
 {
-    return WKBundlePagePolicyActionUse;
+    return WKBundlePagePolicyActionPassThrough;
 }
 
 WKBundlePagePolicyAction InjectedBundlePage::decidePolicyForResponse(WKBundlePageRef page, WKBundleFrameRef, WKURLResponseRef response, WKURLRequestRef, WKTypeRef*)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to