Diff
Modified: trunk/LayoutTests/imported/w3c/ChangeLog (279880 => 279881)
--- trunk/LayoutTests/imported/w3c/ChangeLog 2021-07-13 18:50:07 UTC (rev 279880)
+++ trunk/LayoutTests/imported/w3c/ChangeLog 2021-07-13 19:18:51 UTC (rev 279881)
@@ -1,3 +1,15 @@
+2021-07-13 Chris Dumez <[email protected]>
+
+ Revoking Blob URL after calling XMLHttpRequest::open() causes the XHR to fail
+ https://bugs.webkit.org/show_bug.cgi?id=227821
+
+ Reviewed by Alex Christensen.
+
+ Rebaseline WPT tests now that more checks are passing.
+
+ * web-platform-tests/FileAPI/url/url-with-xhr.any-expected.txt:
+ * web-platform-tests/FileAPI/url/url-with-xhr.any.worker-expected.txt:
+
2021-07-13 Martin Robinson <[email protected]>
RenderLayerScrollableArea::updateScrollPosition assumes that it can scroll to the targeted scroll position
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/FileAPI/url/url-with-xhr.any-expected.txt (279880 => 279881)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/FileAPI/url/url-with-xhr.any-expected.txt 2021-07-13 18:50:07 UTC (rev 279880)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/FileAPI/url/url-with-xhr.any-expected.txt 2021-07-13 19:18:51 UTC (rev 279881)
@@ -12,5 +12,5 @@
PASS XHR with method "PUT" should fail
PASS XHR with method "CUSTOM" should fail
PASS XHR should return Content-Type from Blob
-FAIL Revoke blob URL after open(), will fetch assert_unreached: Got unexpected error event Reached unreachable code
+PASS Revoke blob URL after open(), will fetch
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/FileAPI/url/url-with-xhr.any.worker-expected.txt (279880 => 279881)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/FileAPI/url/url-with-xhr.any.worker-expected.txt 2021-07-13 18:50:07 UTC (rev 279880)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/FileAPI/url/url-with-xhr.any.worker-expected.txt 2021-07-13 19:18:51 UTC (rev 279881)
@@ -12,5 +12,5 @@
PASS XHR with method "PUT" should fail
PASS XHR with method "CUSTOM" should fail
PASS XHR should return Content-Type from Blob
-FAIL Revoke blob URL after open(), will fetch assert_unreached: Got unexpected error event Reached unreachable code
+PASS Revoke blob URL after open(), will fetch
Modified: trunk/Source/WebCore/ChangeLog (279880 => 279881)
--- trunk/Source/WebCore/ChangeLog 2021-07-13 18:50:07 UTC (rev 279880)
+++ trunk/Source/WebCore/ChangeLog 2021-07-13 19:18:51 UTC (rev 279881)
@@ -1,3 +1,36 @@
+2021-07-13 Chris Dumez <[email protected]>
+
+ Revoking Blob URL after calling XMLHttpRequest::open() causes the XHR to fail
+ https://bugs.webkit.org/show_bug.cgi?id=227821
+
+ Reviewed by Alex Christensen.
+
+ Revoking Blob URL after calling XMLHttpRequest::open() causes the XHR to fail. This doesn't match the behavior of
+ other browsers and is causing WebKit to fail one of the subtests on:
+ - http://wpt.live/FileAPI/url/url-with-xhr.any.html
+
+ XMLHttpRequest::open() now extends the lifetime of the Blob URL as necessary in order to complete the load.
+
+ No new tests, rebaselined existing tests.
+
+ * fileapi/BlobURL.cpp:
+ (WebCore::URLWithBlobURLLifetimeExtension::URLWithBlobURLLifetimeExtension):
+ (WebCore::URLWithBlobURLLifetimeExtension::~URLWithBlobURLLifetimeExtension):
+ * fileapi/BlobURL.h:
+ (WebCore::BlobURLLifeTimeExtender::url const):
+ * loader/PolicyChecker.cpp:
+ (WebCore::FrameLoader::PolicyChecker::extendBlobURLLifetimeIfNecessary const):
+ (WebCore::FrameLoader::PolicyChecker::checkNavigationPolicy):
+ * loader/PolicyChecker.h:
+ * xml/XMLHttpRequest.cpp:
+ (WebCore::XMLHttpRequest::XMLHttpRequest):
+ (WebCore::XMLHttpRequest::setResponseType):
+ (WebCore::XMLHttpRequest::open):
+ (WebCore::XMLHttpRequest::prepareToSend):
+ (WebCore::XMLHttpRequest::send):
+ (WebCore::XMLHttpRequest::createRequest):
+ * xml/XMLHttpRequest.h:
+
2021-07-13 Philippe Normand <[email protected]>
[GStreamer] Allow runtime opt-out of GL rendering
Modified: trunk/Source/WebCore/fileapi/BlobURL.cpp (279880 => 279881)
--- trunk/Source/WebCore/fileapi/BlobURL.cpp 2021-07-13 18:50:07 UTC (rev 279880)
+++ trunk/Source/WebCore/fileapi/BlobURL.cpp 2021-07-13 19:18:51 UTC (rev 279881)
@@ -96,4 +96,46 @@
return URL({ }, urlString);
}
+URLWithBlobURLLifetimeExtension::URLWithBlobURLLifetimeExtension(const URL& url)
+ : m_url(url)
+{
+ extendBlobURLLifetimeIfNecessary();
+}
+
+URLWithBlobURLLifetimeExtension::~URLWithBlobURLLifetimeExtension()
+{
+ unregisterCurrentURLIfNecessary();
+}
+
+void URLWithBlobURLLifetimeExtension::extendBlobURLLifetimeIfNecessary()
+{
+ if (m_url.protocolIsBlob()) {
+ auto origin = SecurityOrigin::create(BlobURL::getOriginURL(m_url));
+ URL temporaryBlobURL = BlobURL::createPublicURL(origin.ptr());
+ ThreadableBlobRegistry::registerBlobURL(origin.ptr(), temporaryBlobURL, m_url);
+ m_url = WTFMove(temporaryBlobURL);
+ }
+}
+
+void URLWithBlobURLLifetimeExtension::unregisterCurrentURLIfNecessary()
+{
+ if (m_url.protocolIsBlob())
+ ThreadableBlobRegistry::unregisterBlobURL(m_url);
+}
+
+URLWithBlobURLLifetimeExtension& URLWithBlobURLLifetimeExtension::operator=(URLWithBlobURLLifetimeExtension&& other)
+{
+ unregisterCurrentURLIfNecessary();
+ m_url = std::exchange(other.m_url, { });
+ return *this;
+}
+
+URLWithBlobURLLifetimeExtension& URLWithBlobURLLifetimeExtension::operator=(URL&& url)
+{
+ unregisterCurrentURLIfNecessary();
+ m_url = WTFMove(url);
+ extendBlobURLLifetimeIfNecessary();
+ return *this;
+}
+
} // namespace WebCore
Modified: trunk/Source/WebCore/fileapi/BlobURL.h (279880 => 279881)
--- trunk/Source/WebCore/fileapi/BlobURL.h 2021-07-13 18:50:07 UTC (rev 279880)
+++ trunk/Source/WebCore/fileapi/BlobURL.h 2021-07-13 19:18:51 UTC (rev 279881)
@@ -58,4 +58,29 @@
BlobURL() { }
};
+class URLWithBlobURLLifetimeExtension {
+ WTF_MAKE_FAST_ALLOCATED;
+ WTF_MAKE_NONCOPYABLE(URLWithBlobURLLifetimeExtension);
+public:
+ URLWithBlobURLLifetimeExtension() = default;
+ explicit URLWithBlobURLLifetimeExtension(const URL&);
+ ~URLWithBlobURLLifetimeExtension();
+
+ URLWithBlobURLLifetimeExtension(URLWithBlobURLLifetimeExtension&& other)
+ : m_url(std::exchange(other.m_url, { }))
+ { }
+
+ URLWithBlobURLLifetimeExtension& operator=(URLWithBlobURLLifetimeExtension&&);
+ URLWithBlobURLLifetimeExtension& operator=(URL&&);
+
+ operator const URL&() const { return m_url; }
+ const URL& url() const { return m_url; }
+
+private:
+ void unregisterCurrentURLIfNecessary();
+ void extendBlobURLLifetimeIfNecessary();
+
+ URL m_url;
+};
+
} // namespace WebCore
Modified: trunk/Source/WebCore/loader/PolicyChecker.cpp (279880 => 279881)
--- trunk/Source/WebCore/loader/PolicyChecker.cpp 2021-07-13 18:50:07 UTC (rev 279880)
+++ trunk/Source/WebCore/loader/PolicyChecker.cpp 2021-07-13 19:18:51 UTC (rev 279881)
@@ -104,21 +104,17 @@
checkNavigationPolicy(WTFMove(newRequest), redirectResponse, m_frame.loader().activeDocumentLoader(), { }, WTFMove(function));
}
-CompletionHandlerCallingScope FrameLoader::PolicyChecker::extendBlobURLLifetimeIfNecessary(ResourceRequest& request, DocumentLoader* loader) const
+URLWithBlobURLLifetimeExtension FrameLoader::PolicyChecker::extendBlobURLLifetimeIfNecessary(ResourceRequest& request, DocumentLoader* loader, PolicyDecisionMode mode) const
{
- if (!request.url().protocolIsBlob())
+ if (mode != PolicyDecisionMode::Asynchronous || !request.url().protocolIsBlob())
return { };
- // Create a new temporary blobURL in case this one gets revoked during the asynchronous navigation policy decision.
- auto origin = SecurityOrigin::create(BlobURL::getOriginURL(request.url()));
- URL temporaryBlobURL = BlobURL::createPublicURL(origin.ptr());
- ThreadableBlobRegistry::registerBlobURL(origin.ptr(), temporaryBlobURL, request.url());
- request.setURL(temporaryBlobURL);
+ URLWithBlobURLLifetimeExtension urlWithLifetimeExtension(request.url());
+ request.setURL(urlWithLifetimeExtension);
if (loader)
- loader->request().setURL(temporaryBlobURL);
- return CompletionHandler<void()>([temporaryBlobURL = WTFMove(temporaryBlobURL)] {
- ThreadableBlobRegistry::unregisterBlobURL(temporaryBlobURL);
- });
+ loader->request().setURL(urlWithLifetimeExtension);
+
+ return urlWithLifetimeExtension;
}
void FrameLoader::PolicyChecker::checkNavigationPolicy(ResourceRequest&& request, const ResourceResponse& redirectResponse, DocumentLoader* loader, RefPtr<FormState>&& formState, NavigationPolicyDecisionFunction&& function, PolicyDecisionMode policyDecisionMode)
@@ -201,7 +197,7 @@
m_frame.loader().clearProvisionalLoadForPolicyCheck();
- auto blobURLLifetimeExtension = policyDecisionMode == PolicyDecisionMode::Asynchronous ? extendBlobURLLifetimeIfNecessary(request, loader) : CompletionHandlerCallingScope { };
+ auto blobURLLifetimeExtension = extendBlobURLLifetimeIfNecessary(request, loader, policyDecisionMode);
bool isInitialEmptyDocumentLoad = !m_frame.loader().stateMachine().committedFirstRealDocumentLoad() && request.url().protocolIsAbout() && !substituteData.isValid();
auto requestIdentifier = PolicyCheckIdentifier::create();
Modified: trunk/Source/WebCore/loader/PolicyChecker.h (279880 => 279881)
--- trunk/Source/WebCore/loader/PolicyChecker.h 2021-07-13 18:50:07 UTC (rev 279880)
+++ trunk/Source/WebCore/loader/PolicyChecker.h 2021-07-13 19:18:51 UTC (rev 279881)
@@ -51,6 +51,7 @@
class NavigationAction;
class ResourceError;
class ResourceResponse;
+class URLWithBlobURLLifetimeExtension;
enum class NavigationPolicyDecision : uint8_t {
ContinueLoad,
@@ -89,7 +90,7 @@
private:
void handleUnimplementablePolicy(const ResourceError&);
- WTF::CompletionHandlerCallingScope extendBlobURLLifetimeIfNecessary(ResourceRequest&, DocumentLoader*) const;
+ URLWithBlobURLLifetimeExtension extendBlobURLLifetimeIfNecessary(ResourceRequest&, DocumentLoader*, PolicyDecisionMode = PolicyDecisionMode::Asynchronous) const;
Frame& m_frame;
Modified: trunk/Source/WebCore/xml/XMLHttpRequest.cpp (279880 => 279881)
--- trunk/Source/WebCore/xml/XMLHttpRequest.cpp 2021-07-13 18:50:07 UTC (rev 279880)
+++ trunk/Source/WebCore/xml/XMLHttpRequest.cpp 2021-07-13 19:18:51 UTC (rev 279881)
@@ -251,7 +251,7 @@
// attempt to discourage synchronous XHR use. responseType is one such piece of functionality.
// We'll only disable this functionality for HTTP(S) requests since sync requests for local protocols
// such as file: and data: still make sense to allow.
- if (!m_async && scriptExecutionContext()->isDocument() && m_url.protocolIsInHTTPFamily()) {
+ if (!m_async && scriptExecutionContext()->isDocument() && m_url.url().protocolIsInHTTPFamily()) {
logConsoleError(scriptExecutionContext(), "XMLHttpRequest.responseType cannot be changed for synchronous HTTP(S) requests made from the window context.");
return Exception { InvalidAccessError };
}
@@ -382,8 +382,9 @@
clearResponse();
clearRequest();
- m_url = url;
- context->contentSecurityPolicy()->upgradeInsecureRequestIfNeeded(m_url, ContentSecurityPolicy::InsecureRequestType::Load);
+ auto upgradedURL = url;
+ context->contentSecurityPolicy()->upgradeInsecureRequestIfNeeded(upgradedURL, ContentSecurityPolicy::InsecureRequestType::Load);
+ m_url = WTFMove(upgradedURL);
m_async = async;
@@ -416,7 +417,7 @@
auto& context = *scriptExecutionContext();
if (is<Document>(context) && downcast<Document>(context).shouldIgnoreSyncXHRs()) {
- logConsoleError(scriptExecutionContext(), makeString("Ignoring XMLHttpRequest.send() call for '", m_url.string(), "' because the maximum number of synchronous failures was reached."));
+ logConsoleError(scriptExecutionContext(), makeString("Ignoring XMLHttpRequest.send() call for '", m_url.url().string(), "' because the maximum number of synchronous failures was reached."));
return ExceptionOr<void> { };
}
@@ -515,7 +516,7 @@
return WTFMove(result.value());
if (m_method != "GET" && m_method != "HEAD") {
- if (!m_url.protocolIsInHTTPFamily()) {
+ if (!m_url.url().protocolIsInHTTPFamily()) {
// FIXME: We would like to support posting Blobs to non-http URLs (e.g. custom URL schemes)
// but because of the architecture of blob-handling that will require a fair amount of work.
@@ -588,7 +589,7 @@
ExceptionOr<void> XMLHttpRequest::createRequest()
{
// Only GET request is supported for blob URL.
- if (!m_async && m_url.protocolIsBlob() && m_method != "GET")
+ if (!m_async && m_url.url().protocolIsBlob() && m_method != "GET")
return Exception { NetworkError };
if (m_async && m_upload && m_upload->hasEventListeners())
@@ -740,6 +741,7 @@
{
m_requestHeaders.clear();
m_requestEntityBody = nullptr;
+ m_url = URL { };
}
void XMLHttpRequest::genericError()
@@ -931,6 +933,7 @@
m_responseBuilder.shrinkToFit();
m_loadingActivity = std::nullopt;
+ m_url = URL { };
m_sendFlag = false;
changeState(DONE);
Modified: trunk/Source/WebCore/xml/XMLHttpRequest.h (279880 => 279881)
--- trunk/Source/WebCore/xml/XMLHttpRequest.h 2021-07-13 18:50:07 UTC (rev 279880)
+++ trunk/Source/WebCore/xml/XMLHttpRequest.h 2021-07-13 19:18:51 UTC (rev 279881)
@@ -22,6 +22,7 @@
#pragma once
#include "ActiveDOMObject.h"
+#include "BlobURL.h"
#include "ExceptionOr.h"
#include "FormData.h"
#include "ResourceResponse.h"
@@ -215,7 +216,7 @@
std::unique_ptr<XMLHttpRequestUpload> m_upload;
- URL m_url;
+ URLWithBlobURLLifetimeExtension m_url;
String m_method;
HTTPHeaderMap m_requestHeaders;
RefPtr<FormData> m_requestEntityBody;