Title: [262085] trunk
Revision
262085
Author
[email protected]
Date
2020-05-22 15:50:50 -0700 (Fri, 22 May 2020)

Log Message

Revoking an object URL immediately after triggering navigation causes navigation to fail
https://bugs.webkit.org/show_bug.cgi?id=212279
<rdar://problem/63553090>

Reviewed by Geoffrey Garen.

Source/WebCore:

When doing a policy check for a Blob URL, we clone the blob and create a new temporary Blob URL
that stays alive for the duration of the policy check. We made sure to update the ResourceRequest
URL with the new Blob URL, however, we were failing to update the DocumentLoader's request.
As a result, if the client responded with Policy USE, the DocumentLoader would still attempt to
navigate to the old Blob URL.

Test: fast/loader/revoke-blob-url-after-navigation.html

* loader/PolicyChecker.cpp:
(WebCore::FrameLoader::PolicyChecker::extendBlobURLLifetimeIfNecessary const):
(WebCore::FrameLoader::PolicyChecker::checkNavigationPolicy):
(WebCore::FrameLoader::PolicyChecker::checkNewWindowPolicy):
* loader/PolicyChecker.h:

LayoutTests:

Add layout test coverage.

* fast/loader/revoke-blob-url-after-navigation-expected.txt: Added.
* fast/loader/revoke-blob-url-after-navigation.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (262084 => 262085)


--- trunk/LayoutTests/ChangeLog	2020-05-22 22:43:39 UTC (rev 262084)
+++ trunk/LayoutTests/ChangeLog	2020-05-22 22:50:50 UTC (rev 262085)
@@ -1,3 +1,16 @@
+2020-05-22  Chris Dumez  <[email protected]>
+
+        Revoking an object URL immediately after triggering navigation causes navigation to fail
+        https://bugs.webkit.org/show_bug.cgi?id=212279
+        <rdar://problem/63553090>
+
+        Reviewed by Geoffrey Garen.
+
+        Add layout test coverage.
+
+        * fast/loader/revoke-blob-url-after-navigation-expected.txt: Added.
+        * fast/loader/revoke-blob-url-after-navigation.html: Added.
+
 2020-05-22  Jason Lawrence  <[email protected]>
 
         [ iOS wk2 Release ] editing/async-clipboard/clipboard-item-get-type-basic.html is flaky failing.

Added: trunk/LayoutTests/fast/loader/revoke-blob-url-after-navigation-expected.txt (0 => 262085)


--- trunk/LayoutTests/fast/loader/revoke-blob-url-after-navigation-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/loader/revoke-blob-url-after-navigation-expected.txt	2020-05-22 22:50:50 UTC (rev 262085)
@@ -0,0 +1,11 @@
+Tests that navigation to a Blob URL does not fail if the URL is revoked right after triggering the navigation.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS Was able to navigate the frame
+PASS frame.contentDocument.body.innerText is "TEST"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/fast/loader/revoke-blob-url-after-navigation.html (0 => 262085)


--- trunk/LayoutTests/fast/loader/revoke-blob-url-after-navigation.html	                        (rev 0)
+++ trunk/LayoutTests/fast/loader/revoke-blob-url-after-navigation.html	2020-05-22 22:50:50 UTC (rev 262085)
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script src=""
+<script>
+description("Tests that navigation to a Blob URL does not fail if the URL is revoked right after triggering the navigation.");
+jsTestIsAsync = true;
+
+_onload_ = () => {
+    let url = "" Blob(["TEST", ], { type: 'text/html' }));
+    let link = document.createElement('a');
+    link.target = "testFrame";
+    link.href = ""
+
+    frame = document.getElementById("testFrame");
+    frame._onerror_ = () => {
+        testFailed("Failed to navigate the frame");
+        finishJSTest();
+    }
+
+    frame._onload_ = () => {
+        testPassed("Was able to navigate the frame");
+        shouldBeEqualToString("frame.contentDocument.body.innerText", "TEST");
+        finishJSTest();
+    };
+
+    link.click();
+
+    URL.revokeObjectURL(url);
+    link.remove();
+}
+
+</script>
+<iframe id="testFrame" name="testFrame" src=""
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (262084 => 262085)


--- trunk/Source/WebCore/ChangeLog	2020-05-22 22:43:39 UTC (rev 262084)
+++ trunk/Source/WebCore/ChangeLog	2020-05-22 22:50:50 UTC (rev 262085)
@@ -1,3 +1,25 @@
+2020-05-22  Chris Dumez  <[email protected]>
+
+        Revoking an object URL immediately after triggering navigation causes navigation to fail
+        https://bugs.webkit.org/show_bug.cgi?id=212279
+        <rdar://problem/63553090>
+
+        Reviewed by Geoffrey Garen.
+
+        When doing a policy check for a Blob URL, we clone the blob and create a new temporary Blob URL
+        that stays alive for the duration of the policy check. We made sure to update the ResourceRequest
+        URL with the new Blob URL, however, we were failing to update the DocumentLoader's request.
+        As a result, if the client responded with Policy USE, the DocumentLoader would still attempt to
+        navigate to the old Blob URL.
+
+        Test: fast/loader/revoke-blob-url-after-navigation.html
+
+        * loader/PolicyChecker.cpp:
+        (WebCore::FrameLoader::PolicyChecker::extendBlobURLLifetimeIfNecessary const):
+        (WebCore::FrameLoader::PolicyChecker::checkNavigationPolicy):
+        (WebCore::FrameLoader::PolicyChecker::checkNewWindowPolicy):
+        * loader/PolicyChecker.h:
+
 2020-05-22  Simon Fraser  <[email protected]>
 
         Make sure we clean up CFTimerRefs when destroying scrolling tree nodes

Modified: trunk/Source/WebCore/loader/PolicyChecker.cpp (262084 => 262085)


--- trunk/Source/WebCore/loader/PolicyChecker.cpp	2020-05-22 22:43:39 UTC (rev 262084)
+++ trunk/Source/WebCore/loader/PolicyChecker.cpp	2020-05-22 22:50:50 UTC (rev 262085)
@@ -104,7 +104,7 @@
     checkNavigationPolicy(WTFMove(newRequest), redirectResponse, m_frame.loader().activeDocumentLoader(), { }, WTFMove(function));
 }
 
-CompletionHandlerCallingScope FrameLoader::PolicyChecker::extendBlobURLLifetimeIfNecessary(ResourceRequest& request) const
+CompletionHandlerCallingScope FrameLoader::PolicyChecker::extendBlobURLLifetimeIfNecessary(ResourceRequest& request, DocumentLoader* loader) const
 {
     if (!request.url().protocolIsBlob())
         return { };
@@ -113,6 +113,8 @@
     URL temporaryBlobURL = BlobURL::createPublicURL(&m_frame.document()->securityOrigin());
     blobRegistry().registerBlobURL(temporaryBlobURL, request.url());
     request.setURL(temporaryBlobURL);
+    if (loader)
+        loader->request().setURL(temporaryBlobURL);
     return CompletionHandler<void()>([temporaryBlobURL = WTFMove(temporaryBlobURL)] {
         blobRegistry().unregisterBlobURL(temporaryBlobURL);
     });
@@ -197,7 +199,7 @@
 
     m_frame.loader().clearProvisionalLoadForPolicyCheck();
 
-    auto blobURLLifetimeExtension = policyDecisionMode == PolicyDecisionMode::Asynchronous ? extendBlobURLLifetimeIfNecessary(request) : CompletionHandlerCallingScope { };
+    auto blobURLLifetimeExtension = policyDecisionMode == PolicyDecisionMode::Asynchronous ? extendBlobURLLifetimeIfNecessary(request, loader) : CompletionHandlerCallingScope { };
 
     bool isInitialEmptyDocumentLoad = !m_frame.loader().stateMachine().committedFirstRealDocumentLoad() && request.url().protocolIsAbout() && !substituteData.isValid();
     auto requestIdentifier = PolicyCheckIdentifier::create();
@@ -255,7 +257,7 @@
     if (!DOMWindow::allowPopUp(m_frame))
         return function({ }, nullptr, { }, { }, ShouldContinuePolicyCheck::No);
 
-    auto blobURLLifetimeExtension = extendBlobURLLifetimeIfNecessary(request);
+    auto blobURLLifetimeExtension = extendBlobURLLifetimeIfNecessary(request, nullptr);
 
     auto requestIdentifier = PolicyCheckIdentifier::create();
     m_frame.loader().client().dispatchDecidePolicyForNewWindowAction(navigationAction, request, formState.get(), frameName, requestIdentifier, [frame = makeRef(m_frame), request,

Modified: trunk/Source/WebCore/loader/PolicyChecker.h (262084 => 262085)


--- trunk/Source/WebCore/loader/PolicyChecker.h	2020-05-22 22:43:39 UTC (rev 262084)
+++ trunk/Source/WebCore/loader/PolicyChecker.h	2020-05-22 22:50:50 UTC (rev 262085)
@@ -89,7 +89,7 @@
 
 private:
     void handleUnimplementablePolicy(const ResourceError&);
-    WTF::CompletionHandlerCallingScope extendBlobURLLifetimeIfNecessary(ResourceRequest&) const;
+    WTF::CompletionHandlerCallingScope extendBlobURLLifetimeIfNecessary(ResourceRequest&, DocumentLoader*) const;
 
     Frame& m_frame;
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to