Storage Access API: Make DocumentLoader::willSendRequest() and WebFrameLoaderClient...
authorwilander@apple.com <wilander@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 21 Dec 2017 19:56:45 +0000 (19:56 +0000)
committerwilander@apple.com <wilander@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 21 Dec 2017 19:56:45 +0000 (19:56 +0000)
https://bugs.webkit.org/show_bug.cgi?id=180728
<rdar://problem/36009288>

Reviewed by Youenn Fablet.

Source/WebCore:

Tests: http/tests/storageAccess/request-and-grant-access-then-detach-should-not-have-access.html
       http/tests/storageAccess/request-and-grant-access-then-navigate-should-not-have-access.html

This change calls the network process to clear any storage access
entries when a subframe navigates or is detached.

* dom/Document.cpp:
(WebCore::Document::hasStorageAccess):
(WebCore::Document::requestStorageAccess):
(WebCore::Document::hasFrameSpecificStorageAccess):
(WebCore::Document::setHasFrameSpecificStorageAccess):
* dom/Document.h:
* loader/DocumentLoader.cpp:
(WebCore::DocumentLoader::willSendRequest):
* loader/EmptyFrameLoaderClient.h:
* loader/FrameLoaderClient.h:
* platform/network/NetworkStorageSession.h:
* platform/network/cf/NetworkStorageSessionCFNet.cpp:
(WebCore::NetworkStorageSession::removeStorageAccess):

Source/WebKit:

This change calls the network process to clear any storage access
entries when a subframe navigates or is detached.

* NetworkProcess/NetworkProcess.cpp:
(WebKit::NetworkProcess::removeStorageAccess):
* NetworkProcess/NetworkProcess.h:
* NetworkProcess/NetworkProcess.messages.in:
* UIProcess/Network/NetworkProcessProxy.cpp:
(WebKit::NetworkProcessProxy::removeStorageAccess):
* UIProcess/Network/NetworkProcessProxy.h:
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::removeStorageAccess):
* UIProcess/WebPageProxy.h:
* UIProcess/WebPageProxy.messages.in:
* UIProcess/WebsiteData/WebsiteDataStore.cpp:
(WebKit::WebsiteDataStore::hasStorageAccess):
(WebKit::WebsiteDataStore::requestStorageAccess):
(WebKit::WebsiteDataStore::removeStorageAccess):
* UIProcess/WebsiteData/WebsiteDataStore.h:
* WebProcess/WebCoreSupport/WebChromeClient.cpp:
* WebProcess/WebCoreSupport/WebChromeClient.h:
* WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp:
(WebKit::WebFrameLoaderClient::detachedFromParent2):
(WebKit::WebFrameLoaderClient::dispatchWillChangeDocument):
* WebProcess/WebCoreSupport/WebFrameLoaderClient.h:
* WebProcess/WebPage/WebPage.cpp:
* WebProcess/WebPage/WebPage.h:
* WebProcess/WebPage/WebPage.messages.in:

LayoutTests:

This change calls the network process to clear any storage access
entries when a subframe navigates or is detached.

* http/tests/storageAccess/has-storage-access-from-prevalent-domain-with-non-recent-user-interaction-expected.txt:
* http/tests/storageAccess/has-storage-access-from-prevalent-domain-with-recent-user-interaction-expected.txt:
* http/tests/storageAccess/request-and-deny-storage-access-cross-origin-iframe-expected.txt:
* http/tests/storageAccess/request-and-deny-storage-access-cross-origin-sandboxed-iframe-expected.txt:
* http/tests/storageAccess/request-and-grant-access-then-detach-should-not-have-access-expected.txt: Added.
* http/tests/storageAccess/request-and-grant-access-then-detach-should-not-have-access.html: Added.
* http/tests/storageAccess/request-and-grant-access-then-navigate-should-not-have-access-expected.txt: Added.
* http/tests/storageAccess/request-and-grant-access-then-navigate-should-not-have-access.html: Added.
* http/tests/storageAccess/request-and-grant-storage-access-cross-origin-non-sandboxed-iframe-expected.txt:
* http/tests/storageAccess/request-and-grant-storage-access-cross-origin-sandboxed-iframe-expected.txt:
* http/tests/storageAccess/request-and-grant-storage-access-cross-origin-sandboxed-iframe-from-prevalent-domain-with-non-recent-user-interaction-and-try-access-from-right-frame-expected.txt:
* http/tests/storageAccess/request-and-grant-storage-access-cross-origin-sandboxed-iframe-from-prevalent-domain-with-non-recent-user-interaction-and-try-access-from-right-frame.html:
* http/tests/storageAccess/request-and-grant-storage-access-cross-origin-sandboxed-iframe-from-prevalent-domain-with-non-recent-user-interaction-but-try-access-from-wrong-frame-expected.txt:
* http/tests/storageAccess/request-and-grant-storage-access-cross-origin-sandboxed-iframe-from-prevalent-domain-with-recent-user-interaction-expected.txt:
* http/tests/storageAccess/request-and-grant-storage-access-cross-origin-sandboxed-iframe-from-prevalent-domain-without-user-interaction-expected.txt:
* http/tests/storageAccess/request-and-grant-storage-access-cross-origin-sandboxed-nested-iframe-expected.txt:
* http/tests/storageAccess/request-storage-access-cross-origin-sandboxed-iframe-with-unique-origin-expected.txt:
* http/tests/storageAccess/request-storage-access-cross-origin-sandboxed-iframe-with-unique-origin.html:
* http/tests/storageAccess/request-storage-access-cross-origin-sandboxed-iframe-without-allow-token-expected.txt:
* http/tests/storageAccess/request-storage-access-same-origin-iframe-expected.txt:
* http/tests/storageAccess/request-storage-access-same-origin-sandboxed-iframe-expected.txt:
* http/tests/storageAccess/request-storage-access-same-origin-sandboxed-iframe-without-allow-token-expected.txt:
* http/tests/storageAccess/resources/echo-incoming-cookies-as-json.php: Added.
* http/tests/storageAccess/resources/has-storage-access-iframe.html:
* http/tests/storageAccess/resources/request-storage-access-iframe.html:
* http/tests/storageAccess/resources/self-navigating-frame-after-granted-access.html: Added.
* platform/wk2/TestExpectations:
    Removed http/tests/storageAccess/request-storage-access-top-frame.html
    because it now only passes on High Sierra+.
* platform/mac-wk2/TestExpectations:
    Added the new tests as [ Pass ] on High Sierra+.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@226235 268f45cc-cd09-0410-ab3c-d52691b4dbfc

56 files changed:
LayoutTests/ChangeLog
LayoutTests/http/tests/storageAccess/has-storage-access-from-prevalent-domain-with-non-recent-user-interaction-expected.txt
LayoutTests/http/tests/storageAccess/has-storage-access-from-prevalent-domain-with-recent-user-interaction-expected.txt
LayoutTests/http/tests/storageAccess/request-and-deny-storage-access-cross-origin-iframe-expected.txt
LayoutTests/http/tests/storageAccess/request-and-deny-storage-access-cross-origin-sandboxed-iframe-expected.txt
LayoutTests/http/tests/storageAccess/request-and-grant-access-then-detach-should-not-have-access-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/storageAccess/request-and-grant-access-then-detach-should-not-have-access.html [new file with mode: 0644]
LayoutTests/http/tests/storageAccess/request-and-grant-access-then-navigate-should-not-have-access-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/storageAccess/request-and-grant-access-then-navigate-should-not-have-access.html [new file with mode: 0644]
LayoutTests/http/tests/storageAccess/request-and-grant-storage-access-cross-origin-non-sandboxed-iframe-expected.txt
LayoutTests/http/tests/storageAccess/request-and-grant-storage-access-cross-origin-sandboxed-iframe-expected.txt
LayoutTests/http/tests/storageAccess/request-and-grant-storage-access-cross-origin-sandboxed-iframe-from-prevalent-domain-with-non-recent-user-interaction-and-try-access-from-right-frame-expected.txt
LayoutTests/http/tests/storageAccess/request-and-grant-storage-access-cross-origin-sandboxed-iframe-from-prevalent-domain-with-non-recent-user-interaction-and-try-access-from-right-frame.html
LayoutTests/http/tests/storageAccess/request-and-grant-storage-access-cross-origin-sandboxed-iframe-from-prevalent-domain-with-non-recent-user-interaction-but-try-access-from-wrong-frame-expected.txt
LayoutTests/http/tests/storageAccess/request-and-grant-storage-access-cross-origin-sandboxed-iframe-from-prevalent-domain-with-recent-user-interaction-expected.txt
LayoutTests/http/tests/storageAccess/request-and-grant-storage-access-cross-origin-sandboxed-iframe-from-prevalent-domain-without-user-interaction-expected.txt
LayoutTests/http/tests/storageAccess/request-and-grant-storage-access-cross-origin-sandboxed-nested-iframe-expected.txt
LayoutTests/http/tests/storageAccess/request-storage-access-cross-origin-sandboxed-iframe-with-unique-origin-expected.txt
LayoutTests/http/tests/storageAccess/request-storage-access-cross-origin-sandboxed-iframe-with-unique-origin.html
LayoutTests/http/tests/storageAccess/request-storage-access-cross-origin-sandboxed-iframe-without-allow-token-expected.txt
LayoutTests/http/tests/storageAccess/request-storage-access-same-origin-iframe-expected.txt
LayoutTests/http/tests/storageAccess/request-storage-access-same-origin-sandboxed-iframe-expected.txt
LayoutTests/http/tests/storageAccess/request-storage-access-same-origin-sandboxed-iframe-without-allow-token-expected.txt
LayoutTests/http/tests/storageAccess/resources/echo-incoming-cookies-as-json.php [new file with mode: 0644]
LayoutTests/http/tests/storageAccess/resources/has-storage-access-iframe.html
LayoutTests/http/tests/storageAccess/resources/request-storage-access-iframe.html
LayoutTests/http/tests/storageAccess/resources/self-navigating-frame-after-granted-access.html [new file with mode: 0644]
LayoutTests/platform/mac-wk2/TestExpectations
LayoutTests/platform/wk2/TestExpectations
Source/WebCore/ChangeLog
Source/WebCore/dom/Document.cpp
Source/WebCore/dom/Document.h
Source/WebCore/loader/DocumentLoader.cpp
Source/WebCore/loader/EmptyFrameLoaderClient.h
Source/WebCore/loader/FrameLoaderClient.h
Source/WebCore/platform/network/NetworkStorageSession.h
Source/WebCore/platform/network/cf/NetworkStorageSessionCFNet.cpp
Source/WebKit/ChangeLog
Source/WebKit/NetworkProcess/NetworkProcess.cpp
Source/WebKit/NetworkProcess/NetworkProcess.h
Source/WebKit/NetworkProcess/NetworkProcess.messages.in
Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp
Source/WebKit/UIProcess/Network/NetworkProcessProxy.h
Source/WebKit/UIProcess/WebPageProxy.cpp
Source/WebKit/UIProcess/WebPageProxy.cpp.orig
Source/WebKit/UIProcess/WebPageProxy.h
Source/WebKit/UIProcess/WebPageProxy.messages.in
Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp
Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.h
Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp
Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.h
Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp
Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.h
Source/WebKit/WebProcess/WebPage/WebPage.cpp
Source/WebKit/WebProcess/WebPage/WebPage.h
Source/WebKit/WebProcess/WebPage/WebPage.messages.in

index c063d43..932873f 100644 (file)
@@ -1,3 +1,46 @@
+2017-12-21  John Wilander  <wilander@apple.com>
+
+        Storage Access API: Make DocumentLoader::willSendRequest() and WebFrameLoaderClient::detachedFromParent2() tell the network process to get rid of any sub frame access entries
+        https://bugs.webkit.org/show_bug.cgi?id=180728
+        <rdar://problem/36009288>
+
+        Reviewed by Youenn Fablet.
+
+        This change calls the network process to clear any storage access
+        entries when a subframe navigates or is detached.
+
+        * http/tests/storageAccess/has-storage-access-from-prevalent-domain-with-non-recent-user-interaction-expected.txt:
+        * http/tests/storageAccess/has-storage-access-from-prevalent-domain-with-recent-user-interaction-expected.txt:
+        * http/tests/storageAccess/request-and-deny-storage-access-cross-origin-iframe-expected.txt:
+        * http/tests/storageAccess/request-and-deny-storage-access-cross-origin-sandboxed-iframe-expected.txt:
+        * http/tests/storageAccess/request-and-grant-access-then-detach-should-not-have-access-expected.txt: Added.
+        * http/tests/storageAccess/request-and-grant-access-then-detach-should-not-have-access.html: Added.
+        * http/tests/storageAccess/request-and-grant-access-then-navigate-should-not-have-access-expected.txt: Added.
+        * http/tests/storageAccess/request-and-grant-access-then-navigate-should-not-have-access.html: Added.
+        * http/tests/storageAccess/request-and-grant-storage-access-cross-origin-non-sandboxed-iframe-expected.txt:
+        * http/tests/storageAccess/request-and-grant-storage-access-cross-origin-sandboxed-iframe-expected.txt:
+        * http/tests/storageAccess/request-and-grant-storage-access-cross-origin-sandboxed-iframe-from-prevalent-domain-with-non-recent-user-interaction-and-try-access-from-right-frame-expected.txt:
+        * http/tests/storageAccess/request-and-grant-storage-access-cross-origin-sandboxed-iframe-from-prevalent-domain-with-non-recent-user-interaction-and-try-access-from-right-frame.html:
+        * http/tests/storageAccess/request-and-grant-storage-access-cross-origin-sandboxed-iframe-from-prevalent-domain-with-non-recent-user-interaction-but-try-access-from-wrong-frame-expected.txt:
+        * http/tests/storageAccess/request-and-grant-storage-access-cross-origin-sandboxed-iframe-from-prevalent-domain-with-recent-user-interaction-expected.txt:
+        * http/tests/storageAccess/request-and-grant-storage-access-cross-origin-sandboxed-iframe-from-prevalent-domain-without-user-interaction-expected.txt:
+        * http/tests/storageAccess/request-and-grant-storage-access-cross-origin-sandboxed-nested-iframe-expected.txt:
+        * http/tests/storageAccess/request-storage-access-cross-origin-sandboxed-iframe-with-unique-origin-expected.txt:
+        * http/tests/storageAccess/request-storage-access-cross-origin-sandboxed-iframe-with-unique-origin.html:
+        * http/tests/storageAccess/request-storage-access-cross-origin-sandboxed-iframe-without-allow-token-expected.txt:
+        * http/tests/storageAccess/request-storage-access-same-origin-iframe-expected.txt:
+        * http/tests/storageAccess/request-storage-access-same-origin-sandboxed-iframe-expected.txt:
+        * http/tests/storageAccess/request-storage-access-same-origin-sandboxed-iframe-without-allow-token-expected.txt:
+        * http/tests/storageAccess/resources/echo-incoming-cookies-as-json.php: Added.
+        * http/tests/storageAccess/resources/has-storage-access-iframe.html:
+        * http/tests/storageAccess/resources/request-storage-access-iframe.html:
+        * http/tests/storageAccess/resources/self-navigating-frame-after-granted-access.html: Added.
+        * platform/wk2/TestExpectations:
+            Removed http/tests/storageAccess/request-storage-access-top-frame.html
+            because it now only passes on High Sierra+.
+        * platform/mac-wk2/TestExpectations:
+            Added the new tests as [ Pass ] on High Sierra+.
+
 2017-12-21  Antoine Quint  <graouts@apple.com>
 
         [Web Animations] Complete support for keyframe animations
index 70d5c6b..d044d03 100644 (file)
@@ -3,7 +3,7 @@ Tests that a cross-origin iframe from a prevalent domain with non-recent user in
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
 
-PASS No storage access.
+PASS No storage access. document.cookie == , cookies seen server-side == "No cookies"
 PASS successfullyParsed is true
 
 TEST COMPLETE
index 49d28b9..32a391c 100644 (file)
@@ -3,7 +3,7 @@ Tests that a cross-origin iframe from a prevalent domain with recent user intera
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
 
-PASS Has storage access.
+PASS Has storage access. document.cookie == , cookies seen server-side == "No cookies"
 PASS successfullyParsed is true
 
 TEST COMPLETE
index cad9b6e..ae04d1c 100644 (file)
@@ -3,7 +3,7 @@ Tests that cross-origin iframe storage access is denied if the iframe is not san
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
 
-PASS Storage access was denied.
+PASS Storage access was denied. document.cookie == , cookies seen server-side == "No cookies"
 PASS successfullyParsed is true
 
 TEST COMPLETE
index e3d9803..90c6168 100644 (file)
@@ -4,7 +4,7 @@ Tests that cross-origin iframe storage access is denied if the iframe is sandbox
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
 
-PASS Storage access was denied.
+PASS Storage access was denied. document.cookie == , cookies seen server-side == "No cookies"
 PASS successfullyParsed is true
 
 TEST COMPLETE
diff --git a/LayoutTests/http/tests/storageAccess/request-and-grant-access-then-detach-should-not-have-access-expected.txt b/LayoutTests/http/tests/storageAccess/request-and-grant-access-then-detach-should-not-have-access-expected.txt
new file mode 100644 (file)
index 0000000..48866a4
--- /dev/null
@@ -0,0 +1,12 @@
+CONFIRM: Do you want to use your localhost ID on 127.0.0.1?
+Tests that a cross-origin iframe from a prevalent domain that is granted storage access and then is detached from the DOM does not have storage access.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS Storage access was granted. document.cookie == firstPartyCookie=value, cookies seen server-side == {"firstPartyCookie":"value"}
+PASS PASS. document.cookie == , cookies seen server-side == "No cookies"
+PASS successfullyParsed is true
+
+TEST COMPLETE
diff --git a/LayoutTests/http/tests/storageAccess/request-and-grant-access-then-detach-should-not-have-access.html b/LayoutTests/http/tests/storageAccess/request-and-grant-access-then-detach-should-not-have-access.html
new file mode 100644 (file)
index 0000000..69f161d
--- /dev/null
@@ -0,0 +1,104 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <script src="/js-test-resources/js-test.js"></script>
+    <script src="/js-test-resources/ui-helper.js"></script>
+    <script>
+        description("Tests that a cross-origin iframe from a prevalent domain that is granted storage access and then is detached from the DOM does not have storage access.");
+        jsTestIsAsync = true;
+
+        window.addEventListener("message", receiveMessage, false);
+
+        function setEnableFeature(enable) {
+            if (!enable)
+                testRunner.statisticsResetToConsistentState();
+            internals.setResourceLoadStatisticsEnabled(enable);
+            testRunner.setCookieStoragePartitioningEnabled(enable);
+            testRunner.setStorageAccessAPIEnabled(enable);
+        }
+
+        function finishTest() {
+            setEnableFeature(false);
+            finishJSTest();
+        }
+
+        const iframeID = "TheIframeThatRequestsStorageAccess";
+        function askIframeIfItHasStorageAccess() {
+            var iframeContentWindow = document.getElementById(iframeID).contentWindow;
+            iframeContentWindow.postMessage("reportBackCookies", "http://localhost:8000");
+        }
+
+        function detachIframeAndAskWhetherItStillHasStorageAccess() {
+            var theIframe = document.getElementById(iframeID);
+            theIframe.onload = askIframeIfItHasStorageAccess;
+            document.getElementsByTagName('body')[0].appendChild(theIframe);
+        }
+
+        const expectedPassMessages = 2;
+        var passMessagesReceived = 0;
+        function receiveMessage(event) {
+            if (event.origin === "http://localhost:8000") {
+                if (event.data.indexOf("PASS") !== -1) {
+                    testPassed(event.data.replace("PASS ", ""));
+                    passMessagesReceived++;
+                    if (passMessagesReceived >= expectedPassMessages)
+                        finishTest();
+                    else
+                        detachIframeAndAskWhetherItStillHasStorageAccess();
+                } else {
+                    testFailed(event.data);
+                    finishTest();
+                }
+            } else {
+                testFailed("Received a message from an unexpected origin: " + event.origin);
+                finishTest();
+            }
+        }
+
+        function activateElement(elementId) {
+            var element = document.getElementById(elementId);
+            var centerX = element.offsetLeft + element.offsetWidth / 2;
+            var centerY = element.offsetTop + element.offsetHeight / 2;
+            UIHelper.activateAt(centerX, centerY).then(
+                function () {
+                    if (window.eventSender)
+                        eventSender.keyDown("escape");
+                    else {
+                        testFailed("No eventSender.");
+                        finishTest();
+                    }
+                },
+                function () {
+                    testFailed("Promise rejected.");
+                    finishTest();
+                }
+            );
+        }
+
+        function runTest() {
+            if (document.location.hash !== "#elementActivated") {
+                activateElement(iframeID);
+                document.location.hash = "elementActivated";
+            }
+        }
+
+        const hostUnderTest = "localhost:8000";
+        const statisticsUrl = "http://" + hostUnderTest;
+        if (document.location.hash !== "#firstPartyCookieSet" && document.location.hash !== "#elementActivated") {
+            setEnableFeature(true);
+            document.location.href = statisticsUrl + "/storageAccess/resources/set-cookie.php?name=firstPartyCookie&value=value#http://127.0.0.1:8000/storageAccess/request-and-grant-access-then-detach-should-not-have-access.html#firstPartyCookieSet";
+        } else {
+            testRunner.setStatisticsPrevalentResource(statisticsUrl, true);
+            if (!testRunner.isStatisticsPrevalentResource(statisticsUrl))
+                testFailed("Host did not get set as prevalent resource.");
+            testRunner.setStatisticsHasHadNonRecentUserInteraction(statisticsUrl, true);
+            if (!testRunner.isStatisticsHasHadUserInteraction(statisticsUrl))
+                testFailed("Host did not get logged for user interaction.");
+            testRunner.statisticsUpdateCookiePartitioning();
+        }
+    </script>
+</head>
+<body>
+<iframe sandbox="allow-storage-access-by-user-activation allow-scripts allow-same-origin allow-modals" onload="runTest()" id="TheIframeThatRequestsStorageAccess" src="http://localhost:8000/storageAccess/resources/request-storage-access-iframe.html#userShouldGrantAccess,userShouldBeConsulted,policyShouldGrantAccess"></iframe>
+</body>
+</html>
\ No newline at end of file
diff --git a/LayoutTests/http/tests/storageAccess/request-and-grant-access-then-navigate-should-not-have-access-expected.txt b/LayoutTests/http/tests/storageAccess/request-and-grant-access-then-navigate-should-not-have-access-expected.txt
new file mode 100644 (file)
index 0000000..0c00b95
--- /dev/null
@@ -0,0 +1,14 @@
+CONFIRM: Do you want to use your localhost ID on 127.0.0.1?
+Tests that a cross-origin iframe from a prevalent domain that is granted storage access and then navigates itself does not have storage access.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS document.cookie == 
+PASS Storage access was granted.
+PASS document.cookie == cookieSetClientSideAfterGrantedStorageAccess=value; firstPartyCookie=value
+PASS No storage access. document.cookie == , cookies seen server-side == "No cookies"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/http/tests/storageAccess/request-and-grant-access-then-navigate-should-not-have-access.html b/LayoutTests/http/tests/storageAccess/request-and-grant-access-then-navigate-should-not-have-access.html
new file mode 100644 (file)
index 0000000..2068391
--- /dev/null
@@ -0,0 +1,89 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <script src="/js-test-resources/js-test.js"></script>
+    <script src="/js-test-resources/ui-helper.js"></script>
+    <script>
+        description("Tests that a cross-origin iframe from a prevalent domain that is granted storage access and then navigates itself does not have storage access.");
+        jsTestIsAsync = true;
+
+        window.addEventListener("message", receiveMessage, false);
+
+        function setEnableFeature(enable) {
+            if (!enable)
+                testRunner.statisticsResetToConsistentState();
+            internals.setResourceLoadStatisticsEnabled(enable);
+            testRunner.setCookieStoragePartitioningEnabled(enable);
+            testRunner.setStorageAccessAPIEnabled(enable);
+        }
+
+        function finishTest() {
+            setEnableFeature(false);
+            finishJSTest();
+        }
+
+        const expectedPassMessages = 2;
+        var passMessagesReceived = 0;
+        function receiveMessage(event) {
+            if (event.origin === "http://localhost:8000") {
+                if (event.data.indexOf("document.cookie") === 0) {
+                    testPassed(event.data);
+                } else if (event.data.indexOf("PASS") !== -1) {
+                    testPassed(event.data.replace("PASS ", ""));
+                    passMessagesReceived++;
+                    if (passMessagesReceived >= expectedPassMessages)
+                        finishTest();
+                } else {
+                    testFailed(event.data);
+                    finishTest();
+                }
+            } else {
+                testFailed("Received a message from an unexpected origin: " + event.origin);
+                finishTest();
+            }
+        }
+
+        function activateElement(elementId) {
+            var element = document.getElementById(elementId);
+            var centerX = element.offsetLeft + element.offsetWidth / 2;
+            var centerY = element.offsetTop + element.offsetHeight / 2;
+            UIHelper.activateAt(centerX, centerY).then(
+                function () {
+                    if (window.eventSender)
+                        eventSender.keyDown("escape");
+                    else {
+                        testFailed("No eventSender.");
+                        finishTest();
+                    }
+                },
+                function () {
+                    testFailed("Promise rejected.");
+                    finishTest();
+                }
+            );
+        }
+
+        function runTest() {
+            activateElement("TheIframeThatRequestsStorageAccess");
+        }
+
+        const hostUnderTest = "localhost:8000";
+        const statisticsUrl = "http://" + hostUnderTest;
+        if (document.location.hash !== "#firstPartyCookieSet") {
+            setEnableFeature(true);
+            document.location.href = statisticsUrl + "/storageAccess/resources/set-cookie.php?name=firstPartyCookie&value=value#http://127.0.0.1:8000/storageAccess/request-and-grant-access-then-navigate-should-not-have-access.html#firstPartyCookieSet";
+        } else {
+            testRunner.setStatisticsPrevalentResource(statisticsUrl, true);
+            if (!testRunner.isStatisticsPrevalentResource(statisticsUrl))
+                testFailed("Host did not get set as prevalent resource.");
+            testRunner.setStatisticsHasHadNonRecentUserInteraction(statisticsUrl, true);
+            if (!testRunner.isStatisticsHasHadUserInteraction(statisticsUrl))
+                testFailed("Host did not get logged for user interaction.");
+            testRunner.statisticsUpdateCookiePartitioning();
+        }
+    </script>
+</head>
+<body>
+<iframe sandbox="allow-storage-access-by-user-activation allow-scripts allow-same-origin allow-modals" onload="runTest()" id="TheIframeThatRequestsStorageAccess" src="http://localhost:8000/storageAccess/resources/self-navigating-frame-after-granted-access.html#userShouldGrantAccess,userShouldBeConsulted,policyShouldGrantAccess"></iframe>
+</body>
+</html>
\ No newline at end of file
index cad9b6e..ae04d1c 100644 (file)
@@ -3,7 +3,7 @@ Tests that cross-origin iframe storage access is denied if the iframe is not san
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
 
-PASS Storage access was denied.
+PASS Storage access was denied. document.cookie == , cookies seen server-side == "No cookies"
 PASS successfullyParsed is true
 
 TEST COMPLETE
index 7526bf1..2e80230 100644 (file)
@@ -4,7 +4,7 @@ Tests that cross-origin iframe storage access is granted if the iframe is sandbo
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
 
-PASS Storage access was granted.
+PASS Storage access was granted. document.cookie == , cookies seen server-side == "No cookies"
 PASS successfullyParsed is true
 
 TEST COMPLETE
index 6abe133..c9187ee 100644 (file)
@@ -4,7 +4,7 @@ Tests that cross-origin iframe storage access is granted if the iframe is sandbo
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
 
-PASS Storage access was granted.
+PASS Storage access was granted. document.cookie == firstPartyCookie=value, cookies seen server-side == {"firstPartyCookie":"value"}
 PASS successfullyParsed is true
 
 TEST COMPLETE
@@ -13,10 +13,10 @@ TEST COMPLETE
 --------
 Frame: 'TheIframeThatRequestsStorageAccess'
 --------
-After access granted, should receive first-party cookie.
-Received cookie named 'firstPartyCookie'.
-Did not receive cookie named 'partitionedCookie'.
-Client-side document.cookie: firstPartyCookie=value
+After the top frame navigates the sub frame, the sub frame should no longer have access to first-party cookies.
+Did not receive cookie named 'firstPartyCookie'.
+Received cookie named 'partitionedCookie'.
+Client-side document.cookie: partitionedCookie=value
 
 --------
 Frame: '<!--framePath //<!--frame1-->-->'
index 5c51561..6917171 100644 (file)
                 case "#step7":
                     document.location.hash = "step8";
                     // Check that the first-party cookie gets sent for localhost under 127.0.0.1 since we're opening in the frame that was granted access.
-                    document.getElementById("TheIframeThatRequestsStorageAccess").src = thirdPartyBaseUrl + subPathToGetCookies + "&message=After access granted, should receive first-party cookie.";
+                    document.getElementById("TheIframeThatRequestsStorageAccess").src = thirdPartyBaseUrl + subPathToGetCookies + "&message=After the top frame navigates the sub frame, the sub frame should no longer have access to first-party cookies.";
                     break;
                 case "#step8":
                     setEnableFeature(false);
index ce048a8..393cb53 100644 (file)
@@ -4,7 +4,7 @@ Tests that cross-origin iframe storage access is granted if the iframe is sandbo
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
 
-PASS Storage access was granted.
+PASS Storage access was granted. document.cookie == , cookies seen server-side == "No cookies"
 PASS successfullyParsed is true
 
 TEST COMPLETE
index 6adbefe..0470d0a 100644 (file)
@@ -4,7 +4,7 @@ Tests that cross-origin iframe storage access is denied if the iframe is sandbox
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
 
-PASS Storage access was denied.
+PASS Storage access was denied. document.cookie == , cookies seen server-side == "No cookies"
 PASS successfullyParsed is true
 
 TEST COMPLETE
index 969187e..3e5de6d 100644 (file)
@@ -3,7 +3,7 @@ Tests that cross-origin iframe storage access is denied if the iframe is sandbox
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
 
-PASS Storage access was denied.
+PASS Storage access was denied. document.cookie == , cookies seen server-side == "No cookies"
 PASS successfullyParsed is true
 
 TEST COMPLETE
index 1accaf3..4197646 100644 (file)
@@ -3,7 +3,7 @@ Tests that cross-origin iframe storage access is denied if the iframe is sandbox
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
 
-PASS Storage access was denied.
+PASS Storage access was denied for origin null.
 PASS successfullyParsed is true
 
 TEST COMPLETE
index c0eaf9b..393a7e9 100644 (file)
@@ -46,6 +46,6 @@
     </script>
 </head>
 <body>
-    <iframe sandbox="allow-storage-access-by-user-activation allow-scripts allow-modals" onload="runTest()" id="theIframe" src="http://localhost:8000/storageAccess/resources/request-storage-access-iframe.html#userShouldGrantAccess,userShouldNotBeConsulted,policyShouldDenyAccess,isNotSameOriginIframe"></iframe>
+    <iframe sandbox="allow-storage-access-by-user-activation allow-scripts allow-modals" onload="runTest()" id="theIframe" src="http://localhost:8000/storageAccess/resources/request-storage-access-iframe.html#userShouldGrantAccess,userShouldNotBeConsulted,policyShouldDenyAccess,isNotSameOriginIframe,originIsNull"></iframe>
 </body>
 </html>
\ No newline at end of file
index f562379..c519c7e 100644 (file)
@@ -3,7 +3,7 @@ Tests that cross-origin iframe storage access is denied if the iframe is sandbox
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
 
-PASS Storage access was denied.
+PASS Storage access was denied. document.cookie == , cookies seen server-side == "No cookies"
 PASS successfullyParsed is true
 
 TEST COMPLETE
index e99d7de..de4da86 100644 (file)
@@ -3,7 +3,7 @@ Tests that same-origin iframe storage access is granted if the iframe is not san
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
 
-PASS Storage access was granted.
+PASS Storage access was granted. document.cookie == , cookies seen server-side == "No cookies"
 PASS successfullyParsed is true
 
 TEST COMPLETE
index e981389..c5b0850 100644 (file)
@@ -3,7 +3,7 @@ Tests that same-origin iframe storage access is granted if the iframe is sandbox
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
 
-PASS Storage access was granted.
+PASS Storage access was granted. document.cookie == , cookies seen server-side == "No cookies"
 PASS successfullyParsed is true
 
 TEST COMPLETE
index e1f67df..c1f10e2 100644 (file)
@@ -3,7 +3,7 @@ Tests that same-origin iframe storage access is granted if the iframe is sandbox
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
 
-PASS Storage access was granted.
+PASS Storage access was granted. document.cookie == , cookies seen server-side == "No cookies"
 PASS successfullyParsed is true
 
 TEST COMPLETE
diff --git a/LayoutTests/http/tests/storageAccess/resources/echo-incoming-cookies-as-json.php b/LayoutTests/http/tests/storageAccess/resources/echo-incoming-cookies-as-json.php
new file mode 100644 (file)
index 0000000..2661c20
--- /dev/null
@@ -0,0 +1,7 @@
+<?php
+if(empty($_COOKIE)) {
+    echo json_encode('No cookies');
+} else {
+    echo json_encode($_COOKIE);
+}
+?>
\ No newline at end of file
index 21578c9..327035c 100644 (file)
@@ -3,23 +3,40 @@
     <script>
         const policyShouldGrantAccess = document.location.hash === "#policyShouldGrantAccess";
 
+        function messageToTop(messagePrefix, fetchData) {
+            top.postMessage(messagePrefix + " document.cookie == " + document.cookie +
+                (fetchData ? ", cookies seen server-side == " + JSON.stringify(fetchData) : ""), "http://127.0.0.1:8000");
+        }
+
         function checkHasStorageAccess() {
             var promise = document.hasStorageAccess();
             promise.then(
                 function (hasAccess) {
                     if (hasAccess && policyShouldGrantAccess)
-                        top.postMessage("PASS Has storage access.", "http://127.0.0.1:8000");
+                        fetch("echo-incoming-cookies-as-json.php", { credentials: "same-origin" }).then(function(response) {
+                            return response.json();
+                        }).then(function(data) {
+                            messageToTop("PASS Has storage access.", data);
+                        }).catch(function(error) {
+                            console.log(error.message);
+                        });
                     else if (!hasAccess && !policyShouldGrantAccess)
-                        top.postMessage("PASS No storage access.", "http://127.0.0.1:8000");
+                        fetch("echo-incoming-cookies-as-json.php", { credentials: "same-origin" }).then(function(response) {
+                            return response.json();
+                        }).then(function(data) {
+                            messageToTop("PASS No storage access.", data);
+                        }).catch(function(error) {
+                            console.log(error.message);
+                        });
                     else
-                        top.postMessage("FAIL " +
+                        messageToTop("FAIL " +
                             (hasAccess ? "Storage " : "No storage ") +
                             "access when there should " +
                             (policyShouldGrantAccess ? "" : "not ") +
-                            "have been access.", "http://127.0.0.1:8000");
+                            "have been access.");
                 },
                 function (reason) {
-                    top.postMessage("FAIL document.hasStorageAccess() was rejected. Reason: " + reason, "http://127.0.0.1:8000");
+                    messageToTop("FAIL document.hasStorageAccess() was rejected. Reason: " + reason);
                 }
             );
         }
index 5245141..6afd6c8 100644 (file)
@@ -5,12 +5,43 @@
         const userShouldGrantAccess = hashArguments[0] === "userShouldGrantAccess";
         const userShouldBeConsulted = hashArguments[1] === "userShouldBeConsulted";
         const policyShouldGrantAccess = hashArguments[2] === "policyShouldGrantAccess";
+        const isSameOriginIframe = hashArguments[3] === "isSameOriginIframe";
+        const originIsNull = hashArguments[4] === "originIsNull";
 
         if (internals && userShouldGrantAccess)
                 internals.setUserGrantsStorageAccess(true);
 
         var requestStorageAccessResolved;
 
+        function messageToTop(messagePrefix, fetchData) {
+            if (originIsNull) {
+                top.postMessage(messagePrefix, "http://127.0.0.1:8000");
+            } else {
+                top.postMessage(messagePrefix + " document.cookie == " + document.cookie +
+                    (fetchData ? ", cookies seen server-side == " + JSON.stringify(fetchData) : ""), "http://127.0.0.1:8000");
+            }
+        }
+
+        window.addEventListener("message", receiveMessage, false);
+
+        function receiveMessage(event) {
+            if (event.origin === "http://127.0.0.1:8000") {
+                if (event.data.indexOf("reportBackCookies") !== -1) {
+                    fetch("echo-incoming-cookies-as-json.php", { credentials: "same-origin" }).then(function(response) {
+                        return response.json();
+                    }).then(function(data) {
+                        messageToTop("PASS.", data);
+                    }).catch(function(error) {
+                        console.log(error.message);
+                    });
+                } else {
+                    messageToTop("FAIL Unknown request.");
+                }
+            } else {
+                messageToTop("Fail Received a message from an unexpected origin: " + event.origin);
+            }
+        }
+
         function makeRequestWithUserGesture() {
             var promise = document.requestStorageAccess();
             promise.then(
                     if (requestStorageAccessResolved
                         && hasAccess
                         && (userShouldGrantAccess || !userShouldBeConsulted)
-                        && policyShouldGrantAccess)
-                        top.postMessage("PASS Storage access was granted.", "http://127.0.0.1:8000");
-                    else if (!hasAccess
+                        && policyShouldGrantAccess) {
+                        fetch("echo-incoming-cookies-as-json.php", { credentials: "same-origin" }).then(function(response) {
+                            return response.json();
+                        }).then(function(data) {
+                            messageToTop("PASS Storage access was granted.", data);
+                        }).catch(function(error) {
+                            console.log(error.message);
+                        });
+
+                    } else if (!hasAccess
                         && !requestStorageAccessResolved
-                        && ((!userShouldGrantAccess && userShouldBeConsulted) || !policyShouldGrantAccess))
-                        top.postMessage("PASS Storage access was denied.", "http://127.0.0.1:8000");
-                    else
-                        top.postMessage("FAIL Storage access was " +
+                        && ((!userShouldGrantAccess && userShouldBeConsulted) || !policyShouldGrantAccess)) {
+                        if (originIsNull) {
+                            messageToTop("PASS Storage access was denied for origin null.");
+                        } else {
+                            fetch("echo-incoming-cookies-as-json.php", { credentials: "same-origin" }).then(function(response) {
+                                return response.json();
+                            }).then(function(data) {
+                                messageToTop("PASS Storage access was denied.", data);
+                            }).catch(function(error) {
+                                console.log(error.message);
+                            });
+                        }
+                    } else
+                        messageToTop("FAIL Storage access was " +
                             (hasAccess ? "" : "not ") +
                             "granted and requestStorageAccessResolved was " +
                             (requestStorageAccessResolved ? "" : "not ") +
                             "granted but should " +
                             (userShouldGrantAccess && policyShouldGrantAccess ? "" : "not ") +
-                            "have been granted.", "http://127.0.0.1:8000");
+                            "have been granted.");
                 },
                 function (reason) {
-                    top.postMessage("FAIL document.hasStorageAccess() was rejected. Reason: " + reason, "http://127.0.0.1:8000");
+                    messageToTop("FAIL document.hasStorageAccess() was rejected. Reason: " + reason);
                 }
             );
         }
diff --git a/LayoutTests/http/tests/storageAccess/resources/self-navigating-frame-after-granted-access.html b/LayoutTests/http/tests/storageAccess/resources/self-navigating-frame-after-granted-access.html
new file mode 100644 (file)
index 0000000..6481d59
--- /dev/null
@@ -0,0 +1,72 @@
+<html>
+<head>
+    <script>
+        const hashArguments = document.location.hash.substring(1).split(",");
+        const userShouldGrantAccess = hashArguments[0] === "userShouldGrantAccess";
+        const userShouldBeConsulted = hashArguments[1] === "userShouldBeConsulted";
+        const policyShouldGrantAccess = hashArguments[2] === "policyShouldGrantAccess";
+
+        if (internals && userShouldGrantAccess)
+            internals.setUserGrantsStorageAccess(true);
+
+        var requestStorageAccessResolved;
+
+        function makeRequestWithUserGesture() {
+            var promise = document.requestStorageAccess();
+            promise.then(
+                function () {
+                    requestStorageAccessResolved = true;
+                    continueAfterRequestWithUserGesture();
+                },
+                function () {
+                    requestStorageAccessResolved = false;
+                    continueAfterRequestWithUserGesture();
+                }
+            );
+        }
+
+        function navigate() {
+            document.location.href = "http://localhost:8000/storageAccess/resources/has-storage-access-iframe.html#policyShouldNotGrantAccess"
+        }
+
+        function setCookieAndNavigate() {
+            document.cookie = "cookieSetClientSideAfterGrantedStorageAccess=value";
+            top.postMessage("document.cookie == " + document.cookie, "http://127.0.0.1:8000");
+            setTimeout("navigate()", 200);
+        }
+
+        function continueAfterRequestWithUserGesture() {
+            var promise = document.hasStorageAccess();
+            promise.then(
+                function (hasAccess) {
+                    if (requestStorageAccessResolved
+                        && hasAccess
+                        && (userShouldGrantAccess || !userShouldBeConsulted)
+                        && policyShouldGrantAccess)
+                        top.postMessage("PASS Storage access was granted.", "http://127.0.0.1:8000");
+                    else if (!hasAccess
+                        && !requestStorageAccessResolved
+                        && ((!userShouldGrantAccess && userShouldBeConsulted) || !policyShouldGrantAccess))
+                        top.postMessage("PASS Storage access was denied.", "http://127.0.0.1:8000");
+                    else
+                        top.postMessage("FAIL Storage access was " +
+                            (hasAccess ? "" : "not ") +
+                            "granted and requestStorageAccessResolved was " +
+                            (requestStorageAccessResolved ? "" : "not ") +
+                            "granted but should " +
+                            (userShouldGrantAccess && policyShouldGrantAccess ? "" : "not ") +
+                            "have been granted.", "http://127.0.0.1:8000");
+                    setTimeout("setCookieAndNavigate()", 200);
+                },
+                function (reason) {
+                    top.postMessage("FAIL document.hasStorageAccess() was rejected. Reason: " + reason, "http://127.0.0.1:8000");
+                }
+            );
+        }
+
+        top.postMessage("document.cookie == " + document.cookie, "http://127.0.0.1:8000");
+    </script>
+</head>
+<body onclick="makeRequestWithUserGesture()">
+</body>
+</html>
\ No newline at end of file
index 2d7b025..49feeb6 100644 (file)
@@ -766,6 +766,8 @@ http/tests/resourceLoadStatistics/user-interaction-reported-after-website-data-r
 [ HighSierra+ ] http/tests/storageAccess/request-storage-access-cross-origin-sandboxed-iframe-without-user-gesture.html [ Pass ]
 [ HighSierra+ ] http/tests/storageAccess/has-storage-access-from-prevalent-domain-with-non-recent-user-interaction.html [ Pass ]
 [ HighSierra+ ] http/tests/storageAccess/has-storage-access-from-prevalent-domain-with-recent-user-interaction.html [ Pass ]
+[ HighSierra+ ] http/tests/storageAccess/request-and-grant-access-then-detach-should-not-have-access.html [ Pass ]
+[ HighSierra+ ] http/tests/storageAccess/request-and-grant-access-then-navigate-should-not-have-access.html [ Pass ]
 
 webkit.org/b/173861 [ Release ] http/tests/webrtc/filtering-ice-candidate-same-origin-frame.html [ Pass Timeout ]
 webkit.org/b/173861 [ Release ] http/tests/webrtc/filtering-ice-candidate-cross-origin-frame.html [ Pass Timeout ]
index b04d5fb..74721e3 100644 (file)
@@ -689,7 +689,6 @@ http/tests/resourceLoadStatistics/clear-in-memory-and-persistent-store.html [ Pa
 http/tests/resourceLoadStatistics/grandfathering.html [ Pass ]
 webkit.org/b/180703 http/tests/resourceLoadStatistics/telemetry-generation.html [ Pass Failure ]
 http/tests/resourceLoadStatistics/prune-statistics.html [ Pass ]
-http/tests/storageAccess/request-storage-access-top-frame.html [ Pass ]
 http/tests/resourceLoadStatistics [ Pass ]
 # Cookie partitioning is only supported in macOS High Sierra and iOS 11.
 http/tests/resourceLoadStatistics/add-partitioning-to-redirect.html [ Skip ]
index 37bc26e..61dfc71 100644 (file)
@@ -1,3 +1,31 @@
+2017-12-21  John Wilander  <wilander@apple.com>
+
+        Storage Access API: Make DocumentLoader::willSendRequest() and WebFrameLoaderClient::detachedFromParent2() tell the network process to get rid of any sub frame access entries
+        https://bugs.webkit.org/show_bug.cgi?id=180728
+        <rdar://problem/36009288>
+
+        Reviewed by Youenn Fablet.
+
+        Tests: http/tests/storageAccess/request-and-grant-access-then-detach-should-not-have-access.html
+               http/tests/storageAccess/request-and-grant-access-then-navigate-should-not-have-access.html
+
+        This change calls the network process to clear any storage access
+        entries when a subframe navigates or is detached.
+
+        * dom/Document.cpp:
+        (WebCore::Document::hasStorageAccess):
+        (WebCore::Document::requestStorageAccess):
+        (WebCore::Document::hasFrameSpecificStorageAccess):
+        (WebCore::Document::setHasFrameSpecificStorageAccess):
+        * dom/Document.h:
+        * loader/DocumentLoader.cpp:
+        (WebCore::DocumentLoader::willSendRequest):
+        * loader/EmptyFrameLoaderClient.h:
+        * loader/FrameLoaderClient.h:
+        * platform/network/NetworkStorageSession.h:
+        * platform/network/cf/NetworkStorageSessionCFNet.cpp:
+        (WebCore::NetworkStorageSession::removeStorageAccess):
+
 2017-12-21  Antoine Quint  <graouts@apple.com>
 
         [Web Animations] Complete support for keyframe animations
index 2b12006..bb820fc 100644 (file)
@@ -7432,7 +7432,8 @@ void Document::hasStorageAccess(Ref<DeferredPromise>&& promise)
 {
     ASSERT(settings().storageAccessAPIEnabled());
 
-    if (m_hasFrameSpecificStorageAccess) {
+#if HAVE(CFNETWORK_STORAGE_PARTITIONING)
+    if (hasFrameSpecificStorageAccess()) {
         promise->resolve<IDLBoolean>(true);
         return;
     }
@@ -7454,7 +7455,6 @@ void Document::hasStorageAccess(Ref<DeferredPromise>&& promise)
         return;
     }
 
-    ASSERT(m_frame);
     auto frameID = m_frame->loader().client().frameID();
     auto pageID = m_frame->loader().client().pageID();
     if (!frameID || !pageID) {
@@ -7474,6 +7474,7 @@ void Document::hasStorageAccess(Ref<DeferredPromise>&& promise)
         });
         return;
     }
+#endif
 
     promise->reject();
 }
@@ -7482,8 +7483,11 @@ void Document::requestStorageAccess(Ref<DeferredPromise>&& promise)
 {
     ASSERT(settings().storageAccessAPIEnabled());
     
-    if (m_hasFrameSpecificStorageAccess)
+#if HAVE(CFNETWORK_STORAGE_PARTITIONING)
+    if (hasFrameSpecificStorageAccess()) {
         promise->resolve();
+        return;
+    }
     
     if (!m_frame || securityOrigin().isUnique()) {
         promise->reject();
@@ -7546,17 +7550,30 @@ void Document::requestStorageAccess(Ref<DeferredPromise>&& promise)
                 return;
 
             if (wasGranted) {
-                document->m_hasFrameSpecificStorageAccess = true;
+                document->setHasFrameSpecificStorageAccess(true);
                 promise->resolve();
             } else
                 promise->reject();
         });
         return;
     }
-    
+#endif
+
     promise->reject();
 }
 
+#if HAVE(CFNETWORK_STORAGE_PARTITIONING)
+bool Document::hasFrameSpecificStorageAccess() const
+{
+    return m_frame->loader().client().hasFrameSpecificStorageAccess();
+}
+    
+void Document::setHasFrameSpecificStorageAccess(bool value)
+{
+    m_frame->loader().client().setHasFrameSpecificStorageAccess(value);
+}
+#endif
+
 void Document::setConsoleMessageListener(RefPtr<StringCallback>&& listener)
 {
     m_consoleMessageListener = listener;
index bce8c1b..ebabd9b 100644 (file)
@@ -1699,6 +1699,11 @@ private:
 
     void didLogMessage(const WTFLogChannel&, WTFLogLevel, Vector<JSONLogValue>&&) final;
 
+#if HAVE(CFNETWORK_STORAGE_PARTITIONING)
+    bool hasFrameSpecificStorageAccess() const;
+    void setHasFrameSpecificStorageAccess(bool);
+#endif
+
 #if ENABLE(DEVICE_ORIENTATION) && PLATFORM(IOS)
     std::unique_ptr<DeviceMotionClient> m_deviceMotionClient;
     std::unique_ptr<DeviceMotionController> m_deviceMotionController;
index d3b28b6..1af46d4 100644 (file)
@@ -534,6 +534,9 @@ void DocumentLoader::willSendRequest(ResourceRequest&& newRequest, const Resourc
     if (m_frame->isMainFrame())
         newRequest.setFirstPartyForCookies(newRequest.url());
 
+    if (!didReceiveRedirectResponse)
+        frameLoader()->client().dispatchWillChangeDocument();
+
     // If we're fielding a redirect in response to a POST, force a load from origin, since
     // this is a common site technique to return to a page viewing some data that the POST
     // just modified.
index d2ca9ef..0b13679 100644 (file)
@@ -200,6 +200,10 @@ class WEBCORE_EXPORT EmptyFrameLoaderClient : public FrameLoaderClient {
 #if USE(QUICK_LOOK)
     RefPtr<PreviewLoaderClient> createPreviewLoaderClient(const String&, const String&) final { return nullptr; }
 #endif
+#if HAVE(CFNETWORK_STORAGE_PARTITIONING)
+    bool hasFrameSpecificStorageAccess() final { return false; }
+    void setHasFrameSpecificStorageAccess(bool) final { }
+#endif
 };
 
 }
index 23d0575..7dd25e3 100644 (file)
@@ -161,6 +161,7 @@ public:
     virtual void dispatchDidCancelClientRedirect() = 0;
     virtual void dispatchWillPerformClientRedirect(const URL&, double interval, double fireDate) = 0;
     virtual void dispatchDidChangeMainDocument() { }
+    virtual void dispatchWillChangeDocument() { }
     virtual void dispatchDidNavigateWithinPage() { }
     virtual void dispatchDidChangeLocationWithinPage() = 0;
     virtual void dispatchDidPushStateWithinPage() = 0;
@@ -364,6 +365,11 @@ public:
 #if ENABLE(APPLICATION_MANIFEST)
     virtual void finishedLoadingApplicationManifest(uint64_t, const std::optional<ApplicationManifest>&) { }
 #endif
+
+#if HAVE(CFNETWORK_STORAGE_PARTITIONING)
+    virtual bool hasFrameSpecificStorageAccess() { return false; }
+    virtual void setHasFrameSpecificStorageAccess(bool) { }
+#endif
 };
 
 } // namespace WebCore
index b98f49f..5eb4f0e 100644 (file)
@@ -100,6 +100,7 @@ public:
     WEBCORE_EXPORT void removePrevalentDomains(const Vector<String>& domains);
     WEBCORE_EXPORT bool isStorageAccessGranted(const String& resourceDomain, const String& firstPartyDomain, uint64_t frameID, uint64_t pageID) const;
     WEBCORE_EXPORT void setStorageAccessGranted(const String& resourceDomain, const String& firstPartyDomain, uint64_t frameID, uint64_t pageID, bool value);
+    WEBCORE_EXPORT void removeStorageAccess(uint64_t frameID, uint64_t pageID);
 #endif
 #elif USE(SOUP)
     NetworkStorageSession(PAL::SessionID, std::unique_ptr<SoupNetworkSession>&&);
index 5687f15..178cde7 100644 (file)
@@ -333,6 +333,15 @@ void NetworkStorageSession::setStorageAccessGranted(const String& resourceDomain
     }
 }
 
+void NetworkStorageSession::removeStorageAccess(uint64_t frameID, uint64_t pageID)
+{
+    auto iteration = m_framesGrantedStorageAccess.find(frameID);
+    if (iteration == m_framesGrantedStorageAccess.end())
+        return;
+    
+    iteration->value.remove(pageID);
+}
+    
 #endif // HAVE(CFNETWORK_STORAGE_PARTITIONING)
 
 #if !PLATFORM(COCOA)
index 821260f..78d53e0 100644 (file)
@@ -1,3 +1,40 @@
+2017-12-21  John Wilander  <wilander@apple.com>
+
+        Storage Access API: Make DocumentLoader::willSendRequest() and WebFrameLoaderClient::detachedFromParent2() tell the network process to get rid of any sub frame access entries
+        https://bugs.webkit.org/show_bug.cgi?id=180728
+        <rdar://problem/36009288>
+
+        Reviewed by Youenn Fablet.
+
+        This change calls the network process to clear any storage access
+        entries when a subframe navigates or is detached.
+
+        * NetworkProcess/NetworkProcess.cpp:
+        (WebKit::NetworkProcess::removeStorageAccess):
+        * NetworkProcess/NetworkProcess.h:
+        * NetworkProcess/NetworkProcess.messages.in:
+        * UIProcess/Network/NetworkProcessProxy.cpp:
+        (WebKit::NetworkProcessProxy::removeStorageAccess):
+        * UIProcess/Network/NetworkProcessProxy.h:
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::removeStorageAccess):
+        * UIProcess/WebPageProxy.h:
+        * UIProcess/WebPageProxy.messages.in:
+        * UIProcess/WebsiteData/WebsiteDataStore.cpp:
+        (WebKit::WebsiteDataStore::hasStorageAccess):
+        (WebKit::WebsiteDataStore::requestStorageAccess):
+        (WebKit::WebsiteDataStore::removeStorageAccess):
+        * UIProcess/WebsiteData/WebsiteDataStore.h:
+        * WebProcess/WebCoreSupport/WebChromeClient.cpp:
+        * WebProcess/WebCoreSupport/WebChromeClient.h:
+        * WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp:
+        (WebKit::WebFrameLoaderClient::detachedFromParent2):
+        (WebKit::WebFrameLoaderClient::dispatchWillChangeDocument):
+        * WebProcess/WebCoreSupport/WebFrameLoaderClient.h:
+        * WebProcess/WebPage/WebPage.cpp:
+        * WebProcess/WebPage/WebPage.h:
+        * WebProcess/WebPage/WebPage.messages.in:
+
 2017-12-21  Jeremy Jones  <jeremyj@apple.com>
 
         Second Build fix after r226223
index 4c84aba..4ded64a 100644 (file)
@@ -360,6 +360,14 @@ void NetworkProcess::updateStorageAccessForPrevalentDomains(PAL::SessionID sessi
     parentProcessConnection()->send(Messages::NetworkProcessProxy::StorageAccessRequestResult(isStorageGranted, contextId), 0);
 }
 
+void NetworkProcess::removeStorageAccess(PAL::SessionID sessionID, uint64_t frameID, uint64_t pageID)
+{
+    if (auto* networkStorageSession = NetworkStorageSession::storageSession(sessionID))
+        networkStorageSession->removeStorageAccess(frameID, pageID);
+    else
+        ASSERT_NOT_REACHED();
+}
+
 void NetworkProcess::removePrevalentDomains(PAL::SessionID sessionID, const Vector<String>& domains)
 {
     if (auto* networkStorageSession = NetworkStorageSession::storageSession(sessionID))
index 7625b02..67d2804 100644 (file)
@@ -140,6 +140,7 @@ public:
     void updatePrevalentDomainsToPartitionOrBlockCookies(PAL::SessionID, const Vector<String>& domainsToPartition, const Vector<String>& domainsToBlock, const Vector<String>& domainsToNeitherPartitionNorBlock, bool shouldClearFirst);
     void hasStorageAccessForPrevalentDomains(PAL::SessionID, const String& resourceDomain, const String& firstPartyDomain, uint64_t frameID, uint64_t pageID, uint64_t contextId);
     void updateStorageAccessForPrevalentDomains(PAL::SessionID, const String& resourceDomain, const String& firstPartyDomain, uint64_t frameID, uint64_t pageID, bool value, uint64_t contextId);
+    void removeStorageAccess(PAL::SessionID, uint64_t frameID, uint64_t pageID);
     void removePrevalentDomains(PAL::SessionID, const Vector<String>& domains);
 #endif
 
index f25acec..5bede8e 100644 (file)
@@ -85,6 +85,7 @@ messages -> NetworkProcess LegacyReceiver {
     UpdatePrevalentDomainsToPartitionOrBlockCookies(PAL::SessionID sessionID, Vector<String> domainsToPartition, Vector<String> domainsToBlock, Vector<String> domainsToNeitherPartitionNorBlock, bool shouldClearFirst)
     HasStorageAccessForPrevalentDomains(PAL::SessionID sessionID, String resourceDomain, String firstPartyDomain, uint64_t frameID, uint64_t pageID, uint64_t contextId)
     UpdateStorageAccessForPrevalentDomains(PAL::SessionID sessionID, String resourceDomain, String firstPartyDomain, uint64_t frameID, uint64_t pageID, bool shouldGrantAccess, uint64_t contextId)
+    RemoveStorageAccess(PAL::SessionID sessionID, uint64_t frameID, uint64_t pageID);
     RemovePrevalentDomains(PAL::SessionID sessionID, Vector<String> domainsWithInteraction);
 #endif
 }
index 6ac3782..bd6bf14 100644 (file)
@@ -424,6 +424,11 @@ void NetworkProcessProxy::updateStorageAccessForPrevalentDomains(PAL::SessionID
     send(Messages::NetworkProcess::UpdateStorageAccessForPrevalentDomains(sessionID, resourceDomain, firstPartyDomain, frameID, pageID, value, contextId), 0);
 }
 
+void NetworkProcessProxy::removeStorageAccess(PAL::SessionID sessionID, uint64_t frameID, uint64_t pageID)
+{
+    send(Messages::NetworkProcess::RemoveStorageAccess(sessionID, frameID, pageID), 0);
+}
+
 void NetworkProcessProxy::storageAccessRequestResult(bool wasGranted, uint64_t contextId)
 {
     auto callback = m_storageAccessResponseCallbackMap.take(contextId);
index 48b5f81..68baf68 100644 (file)
@@ -80,6 +80,7 @@ public:
 #if HAVE(CFNETWORK_STORAGE_PARTITIONING)
     void hasStorageAccessForPrevalentDomains(PAL::SessionID, const String& resourceDomain, const String& firstPartyDomain, uint64_t frameID, uint64_t pageID, CompletionHandler<void(bool)>&& callback);
     void updateStorageAccessForPrevalentDomains(PAL::SessionID, const String& resourceDomain, const String& firstPartyDomain, uint64_t frameID, uint64_t pageID, bool value, CompletionHandler<void(bool)>&& callback);
+    void removeStorageAccess(PAL::SessionID, uint64_t frameID, uint64_t pageID);
 #endif
 
     void processReadyToSuspend();
index 279480a..db3f31a 100644 (file)
@@ -7182,6 +7182,7 @@ void WebPageProxy::stopURLSchemeTask(uint64_t handlerIdentifier, uint64_t taskId
     iterator->value->stopTask(*this, taskIdentifier);
 }
 
+#if HAVE(CFNETWORK_STORAGE_PARTITIONING)
 void WebPageProxy::hasStorageAccess(String&& subFrameHost, String&& topFrameHost, uint64_t frameID, uint64_t pageID, uint64_t webProcessContextId)
 {
     m_websiteDataStore->hasStorageAccess(WTFMove(subFrameHost), WTFMove(topFrameHost), frameID, pageID, [this, webProcessContextId] (bool hasAccess) {
@@ -7197,6 +7198,13 @@ void WebPageProxy::requestStorageAccess(String&& subFrameHost, String&& topFrame
     });
 }
 
+void WebPageProxy::removeStorageAccess(uint64_t frameID, uint64_t pageID)
+{
+    ASSERT(pageID == m_pageID);
+    m_websiteDataStore->removeStorageAccess(frameID, pageID);
+}
+#endif
+
 #if PLATFORM(COCOA)
 void WebPageProxy::touchBarMenuDataChanged(const TouchBarMenuData& touchBarMenuData)
 {
index 4bbe8db..279480a 100644 (file)
@@ -6928,11 +6928,6 @@ void WebPageProxy::handleAutoFillButtonClick(const UserData& userData)
     m_uiClient->didClickAutoFillButton(*this, m_process->transformHandlesToObjects(userData.object()).get());
 }
 
-void WebPageProxy::handleAlternativePresentationButtonClick(const UserData& userData)
-{
-    m_uiClient->didClickAlternativePresentationButton(*this, m_process->transformHandlesToObjects(userData.object()).get());
-}
-
 #if ENABLE(WIRELESS_PLAYBACK_TARGET) && !PLATFORM(IOS)
 void WebPageProxy::addPlaybackTargetPickerClient(uint64_t contextId)
 {
index 8014906..3f39ed0 100644 (file)
@@ -1246,8 +1246,11 @@ public:
     void touchBarMenuItemDataRemoved(const TouchBarMenuItemData&);
 #endif
 
+#if HAVE(CFNETWORK_STORAGE_PARTITIONING)
     void hasStorageAccess(String&& subFrameHost, String&& topFrameHost, uint64_t frameID, uint64_t pageID, uint64_t webProcessContextId);
     void requestStorageAccess(String&& subFrameHost, String&& topFrameHost, uint64_t frameID, uint64_t pageID, uint64_t webProcessContextId);
+    void removeStorageAccess(uint64_t frameID, uint64_t pageID);
+#endif
 
 #if ENABLE(ATTACHMENT_ELEMENT)
     void insertAttachment(const String& identifier, const WebCore::AttachmentDisplayOptions&, const String& filename, std::optional<String> contentType, WebCore::SharedBuffer& data, Function<void(CallbackBase::Error)>&&);
index cfde698..60485ae 100644 (file)
@@ -505,8 +505,11 @@ messages -> WebPageProxy {
     StartURLSchemeTask(struct WebKit::URLSchemeTaskParameters parameters)
     StopURLSchemeTask(uint64_t handlerIdentifier, uint64_t taskIdentifier)
 
+#if HAVE(CFNETWORK_STORAGE_PARTITIONING)
     HasStorageAccess(String subFrameHost, String topFrameHost, uint64_t frameID, uint64_t pageID, uint64_t contextID)
     RequestStorageAccess(String subFrameHost, String topFrameHost, uint64_t frameID, uint64_t pageID, uint64_t contextID)
+    RemoveStorageAccess(uint64_t frameID, uint64_t pageID)
+#endif
 
 #if ENABLE(ATTACHMENT_ELEMENT)
     DidInsertAttachment(String identifier)
index b373f99..8343d72 100644 (file)
@@ -1193,6 +1193,32 @@ void WebsiteDataStore::removePrevalentDomains(const Vector<String>& domains)
     for (auto& processPool : processPools())
         processPool->sendToNetworkingProcess(Messages::NetworkProcess::RemovePrevalentDomains(m_sessionID, domains));
 }
+
+void WebsiteDataStore::hasStorageAccess(String&& subFrameHost, String&& topFrameHost, uint64_t frameID, uint64_t pageID, WTF::CompletionHandler<void (bool)>&& callback)
+{
+    if (!resourceLoadStatisticsEnabled()) {
+        callback(false);
+        return;
+    }
+    
+    m_resourceLoadStatistics->hasStorageAccess(WTFMove(subFrameHost), WTFMove(topFrameHost), frameID, pageID, WTFMove(callback));
+}
+
+void WebsiteDataStore::requestStorageAccess(String&& subFrameHost, String&& topFrameHost, uint64_t frameID, uint64_t pageID, WTF::CompletionHandler<void (bool)>&& callback)
+{
+    if (!resourceLoadStatisticsEnabled()) {
+        callback(false);
+        return;
+    }
+    
+    m_resourceLoadStatistics->requestStorageAccess(WTFMove(subFrameHost), WTFMove(topFrameHost), frameID, pageID, WTFMove(callback));
+}
+
+void WebsiteDataStore::removeStorageAccess(uint64_t frameID, uint64_t pageID)
+{
+    for (auto& processPool : processPools())
+        processPool->networkProcess()->removeStorageAccess(m_sessionID, frameID, pageID);
+}
 #endif
 
 void WebsiteDataStore::networkProcessDidCrash()
@@ -1444,26 +1470,6 @@ void WebsiteDataStore::removePendingCookie(const WebCore::Cookie& cookie)
     m_pendingCookies.remove(cookie);
 }
 
-void WebsiteDataStore::hasStorageAccess(String&& subFrameHost, String&& topFrameHost, uint64_t frameID, uint64_t pageID, WTF::CompletionHandler<void (bool)>&& callback)
-{
-    if (!resourceLoadStatisticsEnabled()) {
-        callback(false);
-        return;
-    }
-    
-    m_resourceLoadStatistics->hasStorageAccess(WTFMove(subFrameHost), WTFMove(topFrameHost), frameID, pageID, WTFMove(callback));
-}
-    
-void WebsiteDataStore::requestStorageAccess(String&& subFrameHost, String&& topFrameHost, uint64_t frameID, uint64_t pageID, WTF::CompletionHandler<void (bool)>&& callback)
-{
-    if (!resourceLoadStatisticsEnabled()) {
-        callback(false);
-        return;
-    }
-
-    m_resourceLoadStatistics->requestStorageAccess(WTFMove(subFrameHost), WTFMove(topFrameHost), frameID, pageID, WTFMove(callback));
-}
-
 #if !PLATFORM(COCOA)
 WebsiteDataStoreParameters WebsiteDataStore::parameters()
 {
index 78e6595..1944988 100644 (file)
@@ -121,6 +121,9 @@ public:
     void hasStorageAccessForPrevalentDomainsHandler(const String& resourceDomain, const String& firstPartyDomain, uint64_t frameID, uint64_t pageID, WTF::CompletionHandler<void(bool hasAccess)>&& callback);
     void updateStorageAccessForPrevalentDomainsHandler(const String& resourceDomain, const String& firstPartyDomain, uint64_t frameID, uint64_t pageID, bool value, WTF::CompletionHandler<void(bool wasGranted)>&& callback);
     void removePrevalentDomains(const Vector<String>& domains);
+    void hasStorageAccess(String&& subFrameHost, String&& topFrameHost, uint64_t frameID, uint64_t pageID, WTF::CompletionHandler<void (bool)>&& callback);
+    void requestStorageAccess(String&& subFrameHost, String&& topFrameHost, uint64_t frameID, uint64_t pageID, WTF::CompletionHandler<void (bool)>&& callback);
+    void removeStorageAccess(uint64_t frameID, uint64_t pageID);
 #endif
     void networkProcessDidCrash();
     void resolveDirectoriesIfNecessary();
@@ -147,9 +150,6 @@ public:
 
     void enableResourceLoadStatisticsAndSetTestingCallback(Function<void (const String&)>&& callback);
 
-    void hasStorageAccess(String&& subFrameHost, String&& topFrameHost, uint64_t frameID, uint64_t pageID, WTF::CompletionHandler<void (bool)>&& callback);
-    void requestStorageAccess(String&& subFrameHost, String&& topFrameHost, uint64_t frameID, uint64_t pageID, WTF::CompletionHandler<void (bool)>&& callback);
-    
     void setBoundInterfaceIdentifier(String&& identifier) { m_boundInterfaceIdentifier = WTFMove(identifier); }
     const String& boundInterfaceIdentifier() { return m_boundInterfaceIdentifier; }
     
index cfe583d..66a52b4 100644 (file)
@@ -1253,6 +1253,7 @@ void WebChromeClient::didInvalidateDocumentMarkerRects()
     m_page.findController().didInvalidateDocumentMarkerRects();
 }
 
+#if HAVE(CFNETWORK_STORAGE_PARTITIONING)
 void WebChromeClient::hasStorageAccess(String&& subFrameHost, String&& topFrameHost, uint64_t frameID, uint64_t pageID, WTF::CompletionHandler<void (bool)>&& callback)
 {
     m_page.hasStorageAccess(WTFMove(subFrameHost), WTFMove(topFrameHost), frameID, pageID, WTFMove(callback));
@@ -1262,5 +1263,6 @@ void WebChromeClient::requestStorageAccess(String&& subFrameHost, String&& topFr
 {
     m_page.requestStorageAccess(WTFMove(subFrameHost), WTFMove(topFrameHost), frameID, pageID, WTFMove(callback));
 }
+#endif
 
 } // namespace WebKit
index 2824049..e48bda3 100644 (file)
@@ -348,8 +348,10 @@ private:
 
     void didInvalidateDocumentMarkerRects() final;
 
+#if HAVE(CFNETWORK_STORAGE_PARTITIONING)
     void hasStorageAccess(String&& subFrameHost, String&& topFrameHost, uint64_t frameID, uint64_t pageID, WTF::CompletionHandler<void (bool)>&&) final;
     void requestStorageAccess(String&& subFrameHost, String&& topFrameHost, uint64_t frameID, uint64_t pageID, WTF::CompletionHandler<void (bool)>&&) final;
+#endif
 
     String m_cachedToolTip;
     mutable RefPtr<WebFrame> m_cachedFrameSetLargestFrame;
index cb1e24f..93fd552 100644 (file)
@@ -166,6 +166,13 @@ void WebFrameLoaderClient::detachedFromParent2()
     if (!webPage)
         return;
 
+#if HAVE(CFNETWORK_STORAGE_PARTITIONING)
+    if (m_hasFrameSpecificStorageAccess) {
+        webPage->send(Messages::WebPageProxy::RemoveStorageAccess(frameID().value(), pageID().value()));
+        m_hasFrameSpecificStorageAccess = false;
+    }
+#endif
+
     RefPtr<API::Object> userData;
 
     // Notify the bundle client.
@@ -372,6 +379,23 @@ void WebFrameLoaderClient::dispatchDidChangeMainDocument()
     webPage->send(Messages::WebPageProxy::DidChangeMainDocument(m_frame->frameID()));
 }
 
+void WebFrameLoaderClient::dispatchWillChangeDocument()
+{
+#if HAVE(CFNETWORK_STORAGE_PARTITIONING)
+    if (m_frame->isMainFrame())
+        return;
+
+    WebPage* webPage = m_frame->page();
+    if (!webPage)
+        return;
+
+    if (m_hasFrameSpecificStorageAccess) {
+        webPage->send(Messages::WebPageProxy::RemoveStorageAccess(frameID().value(), pageID().value()));
+        m_hasFrameSpecificStorageAccess = false;
+    }
+#endif
+}
+
 void WebFrameLoaderClient::dispatchDidPushStateWithinPage()
 {
     WebPage* webPage = m_frame->page();
index 0ced8bd..b68032e 100644 (file)
@@ -55,6 +55,11 @@ public:
     std::optional<uint64_t> frameID() const final;
     PAL::SessionID sessionID() const final;
 
+#if HAVE(CFNETWORK_STORAGE_PARTITIONING)
+    bool hasFrameSpecificStorageAccess() { return m_hasFrameSpecificStorageAccess; }
+    void setHasFrameSpecificStorageAccess(bool value) { m_hasFrameSpecificStorageAccess = value; };
+#endif
+    
 private:
     void frameLoaderDestroyed() final;
 
@@ -92,6 +97,7 @@ private:
     void dispatchDidFinishDataDetection(NSArray *detectionResults) final;
 #endif
     void dispatchDidChangeMainDocument() final;
+    void dispatchWillChangeDocument() final;
 
     void dispatchDidDispatchOnloadEvents() final;
     void dispatchDidReceiveServerRedirectForProvisionalLoad() final;
@@ -273,6 +279,9 @@ private:
     bool m_frameHasCustomContentProvider;
     bool m_frameCameFromPageCache;
     bool m_useIconLoadingClient { false };
+#if HAVE(CFNETWORK_STORAGE_PARTITIONING)
+    bool m_hasFrameSpecificStorageAccess { false };
+#endif
 };
 
 // As long as EmptyFrameLoaderClient exists in WebCore, this can return 0.
index c302c59..41c5cee 100644 (file)
@@ -5798,6 +5798,7 @@ void WebPage::urlSchemeTaskDidComplete(uint64_t handlerIdentifier, uint64_t task
     handler->taskDidComplete(taskIdentifier, error);
 }
 
+#if HAVE(CFNETWORK_STORAGE_PARTITIONING)
 static uint64_t nextRequestStorageAccessContextId()
 {
     static uint64_t nextContextId = 0;
@@ -5832,6 +5833,7 @@ void WebPage::storageAccessResponse(bool wasGranted, uint64_t contextId)
     ASSERT(callback);
     callback(wasGranted);
 }
+#endif
 
 void WebPage::invokeSharedBufferCallback(RefPtr<SharedBuffer>&& buffer, CallbackID callbackID)
 {
index e4ebc32..04df6de 100644 (file)
@@ -1032,9 +1032,11 @@ public:
     void sendPartialEditorStateAndSchedulePostLayoutUpdate();
     void flushPendingEditorStateUpdate();
 
+#if HAVE(CFNETWORK_STORAGE_PARTITIONING)
     void hasStorageAccess(String&& subFrameHost, String&& topFrameHost, uint64_t frameID, uint64_t pageID, WTF::CompletionHandler<void (bool)>&& callback);
     void requestStorageAccess(String&& subFrameHost, String&& topFrameHost, uint64_t frameID, uint64_t pageID, WTF::CompletionHandler<void (bool)>&& callback);
     void storageAccessResponse(bool wasGranted, uint64_t contextId);
+#endif
 
 #if ENABLE(ATTACHMENT_ELEMENT)
     void insertAttachment(const String& identifier, const WebCore::AttachmentDisplayOptions&, const String& filename, std::optional<String> contentType, const IPC::DataReference&, CallbackID);
index 0234515..4e43bc7 100644 (file)
@@ -488,7 +488,9 @@ messages -> WebPage LegacyReceiver {
     URLSchemeTaskDidReceiveData(uint64_t handlerIdentifier, uint64_t taskIdentifier, IPC::DataReference data)
     URLSchemeTaskDidComplete(uint64_t handlerIdentifier, uint64_t taskIdentifier, WebCore::ResourceError error)
 
+#if HAVE(CFNETWORK_STORAGE_PARTITIONING)
     StorageAccessResponse(bool wasGranted, uint64_t contextId)
+#endif
 
 #if ENABLE(ATTACHMENT_ELEMENT)
     InsertAttachment(String identifier, struct WebCore::AttachmentDisplayOptions options, String filename, std::optional<String> contentType, IPC::DataReference data, WebKit::CallbackID callbackID)