Diff
Modified: trunk/LayoutTests/ChangeLog (280823 => 280824)
--- trunk/LayoutTests/ChangeLog 2021-08-10 03:11:48 UTC (rev 280823)
+++ trunk/LayoutTests/ChangeLog 2021-08-10 03:33:03 UTC (rev 280824)
@@ -1,3 +1,15 @@
+2021-08-09 Chris Dumez <[email protected]>
+
+ Blob URL changes after loading it
+ https://bugs.webkit.org/show_bug.cgi?id=228923
+
+ Reviewed by Geoff Garen.
+
+ Add layout test coverage.
+
+ * fast/files/blob-as-frame-url-expected.txt: Added.
+ * fast/files/blob-as-frame-url.html: Added.
+
2021-08-09 Lauro Moura <[email protected]>
[GLIB] Garden two getUserMedia timeouts
Modified: trunk/LayoutTests/fast/dom/HTMLAnchorElement/anchor-file-blob-download-then-revoke-expected.txt (280823 => 280824)
--- trunk/LayoutTests/fast/dom/HTMLAnchorElement/anchor-file-blob-download-then-revoke-expected.txt 2021-08-10 03:11:48 UTC (rev 280823)
+++ trunk/LayoutTests/fast/dom/HTMLAnchorElement/anchor-file-blob-download-then-revoke-expected.txt 2021-08-10 03:33:03 UTC (rev 280824)
@@ -1,4 +1,3 @@
-CONSOLE MESSAGE: PASS: URL was revoked
Download started.
Downloading URL with suggested filename "foo.txt"
Download completed.
Modified: trunk/LayoutTests/fast/dom/HTMLAnchorElement/anchor-file-blob-download-then-revoke.html (280823 => 280824)
--- trunk/LayoutTests/fast/dom/HTMLAnchorElement/anchor-file-blob-download-then-revoke.html 2021-08-10 03:11:48 UTC (rev 280823)
+++ trunk/LayoutTests/fast/dom/HTMLAnchorElement/anchor-file-blob-download-then-revoke.html 2021-08-10 03:33:03 UTC (rev 280824)
@@ -23,18 +23,6 @@
link.click();
// Revoke the URL right away.
window.URL.revokeObjectURL(link.href);
-
- // Make sure the URL was revoked.
- xhr = new XMLHttpRequest();
- xhr.open("GET", link.href, false);
- try {
- xhr.send(null);
- } catch (e) {
- }
- if (xhr.status == 200)
- console.log("FAIL: URL was not revoked");
- else
- console.log("PASS: URL was revoked");
}
runTest();
</script>
Added: trunk/LayoutTests/fast/files/blob-as-frame-url-expected.txt (0 => 280824)
--- trunk/LayoutTests/fast/files/blob-as-frame-url-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/files/blob-as-frame-url-expected.txt 2021-08-10 03:33:03 UTC (rev 280824)
@@ -0,0 +1,12 @@
+Makes sure that using a Blob URL as frame URL works as expected.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS iframe.contentDocument.body.innerText is "FOO"
+PASS iframe.contentWindow.location.href == blobURL is true
+PASS iframe.contentDocument.URL == blobURL is true
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/fast/files/blob-as-frame-url.html (0 => 280824)
--- trunk/LayoutTests/fast/files/blob-as-frame-url.html (rev 0)
+++ trunk/LayoutTests/fast/files/blob-as-frame-url.html 2021-08-10 03:33:03 UTC (rev 280824)
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script src=""
+<script>
+description("Makes sure that using a Blob URL as frame URL works as expected.");
+jsTestIsAsync = true;
+
+let blobContents = `<body>FOO</body>`;
+let iframe = document.createElement("iframe");
+let blob = new Blob([blobContents], { type: "text/html" });
+let blobURL = URL.createObjectURL(blob);
+iframe.src = ""
+iframe._onload_ = () => {
+ shouldBeEqualToString("iframe.contentDocument.body.innerText", "FOO");
+ shouldBeTrue("iframe.contentWindow.location.href == blobURL");
+ shouldBeTrue("iframe.contentDocument.URL == blobURL");
+ finishJSTest();
+};
+document.body.append(iframe);
+blob = null;
+gc();
+setTimeout(gc, 0);
+</script>
+</body>
+</html>
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/FileAPI/url/url-in-tags.window-expected.txt (280823 => 280824)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/FileAPI/url/url-in-tags.window-expected.txt 2021-08-10 03:11:48 UTC (rev 280823)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/FileAPI/url/url-in-tags.window-expected.txt 2021-08-10 03:33:03 UTC (rev 280824)
@@ -1,7 +1,5 @@
-Harness Error (TIMEOUT), message = null
-
PASS Blob URLs can be used in <script> tags
PASS Blob URLs can be used in iframes, and are treated same origin
-TIMEOUT Blob URL fragment is implemented. Test timed out
+PASS Blob URL fragment is implemented.
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/FileAPI/url/url-reload.window-expected.txt (280823 => 280824)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/FileAPI/url/url-reload.window-expected.txt 2021-08-10 03:11:48 UTC (rev 280823)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/FileAPI/url/url-reload.window-expected.txt 2021-08-10 03:33:03 UTC (rev 280824)
@@ -1,6 +1,6 @@
Harness Error (TIMEOUT), message = null
-TIMEOUT Reloading a blob URL succeeds. Test timed out
+PASS Reloading a blob URL succeeds.
TIMEOUT Reloading a blob URL succeeds even if the URL was revoked. Test timed out
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/content-security-policy/inheritance/history.sub-expected.txt (280823 => 280824)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/content-security-policy/inheritance/history.sub-expected.txt 2021-08-10 03:11:48 UTC (rev 280823)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/content-security-policy/inheritance/history.sub-expected.txt 2021-08-10 03:33:03 UTC (rev 280824)
@@ -1,8 +1,8 @@
PASS History navigation: "about:blank" document is navigated back from history same-origin.
PASS History navigation: "about:blank" document is navigated back from history cross-origin.
-FAIL History navigation: blob URL document is navigated back from history same-origin. step_wait_func: Wait for the popup to navigate. Timed out waiting on condition
-FAIL History navigation: blob URL document is navigated back from history cross-origin. step_wait_func: Wait for the popup to navigate. Timed out waiting on condition
-FAIL History navigation: blob URL document is navigated back from history (without bfcache on Firefox) same-origin. step_wait_func: Wait for the popup to navigate. Timed out waiting on condition
-FAIL History navigation: blob URL document is navigated back from history (without bfcache on Firefox) cross-origin. step_wait_func: Wait for the popup to navigate. Timed out waiting on condition
+FAIL History navigation: blob URL document is navigated back from history same-origin. assert_equals: Image should be blocked by CSP inherited from navigation initiator. expected "img blocked" but got "img loaded"
+FAIL History navigation: blob URL document is navigated back from history cross-origin. assert_equals: Image should be blocked by CSP inherited from navigation initiator. expected "img blocked" but got "img loaded"
+FAIL History navigation: blob URL document is navigated back from history (without bfcache on Firefox) same-origin. assert_equals: Image should be blocked by CSP inherited from navigation initiator. expected "img blocked" but got "img loaded"
+FAIL History navigation: blob URL document is navigated back from history (without bfcache on Firefox) cross-origin. assert_equals: Image should be blocked by CSP inherited from navigation initiator. expected "img blocked" but got "img loaded"
Modified: trunk/Source/WebCore/ChangeLog (280823 => 280824)
--- trunk/Source/WebCore/ChangeLog 2021-08-10 03:11:48 UTC (rev 280823)
+++ trunk/Source/WebCore/ChangeLog 2021-08-10 03:33:03 UTC (rev 280824)
@@ -1,3 +1,83 @@
+2021-08-09 Chris Dumez <[email protected]>
+
+ Blob URL changes after loading it
+ https://bugs.webkit.org/show_bug.cgi?id=228923
+
+ Reviewed by Geoff Garen.
+
+ Blob URL changes after loading it. This is because we use URLWithBlobURLLifetimeExtension to
+ extend the lifetime of the Blob URL during the load and URLWithBlobURLLifetimeExtension ends
+ up creating a new public Blob URL. This is Web-observable so we need a way to extend the
+ lifetime of a Blob URL without actually generating a new Blob URL.
+
+ This patch replaces URLWithBlobURLLifetimeExtension with a new BlobURLHandle class which
+ extends the lifetime of a Blob URL as long as there are BlobURLHandle objects referring
+ to it. BlobURLHandle works with both private and public Blob URLs so it replaces
+ Blob::Handle as well (which I recently introduced via r280547). The Blob URL no longer
+ changes when we extend its lifetime. Instead, the Blob registry now keeps track of
+ references to a given Blob and only removes a Blob URL once there are no longer any
+ references to it.
+
+ Test: fast/files/blob-as-frame-url.html
+
+ * Headers.cmake:
+ * WebCore.xcodeproj/project.pbxproj:
+ * bindings/js/SerializedScriptValue.cpp:
+ (WebCore::CloneSerializer::serialize):
+ (WebCore::CloneSerializer::CloneSerializer):
+ (WebCore::CloneSerializer::dumpIfTerminal):
+ (WebCore::SerializedScriptValue::SerializedScriptValue):
+ (WebCore::SerializedScriptValue::create):
+ * bindings/js/SerializedScriptValue.h:
+ (WebCore::SerializedScriptValue::blobHandles const):
+ (WebCore::SerializedScriptValue::SerializedScriptValue):
+ * fileapi/Blob.cpp:
+ (WebCore::Blob::Blob):
+ (WebCore::Blob::slice const):
+ (WebCore::Blob::size const):
+ (WebCore::Blob::handle const):
+ * fileapi/Blob.h:
+ (WebCore::Blob::url const):
+ * fileapi/BlobURL.cpp:
+ (WebCore::BlobURLHandle::BlobURLHandle):
+ (WebCore::BlobURLHandle::~BlobURLHandle):
+ (WebCore::BlobURLHandle::registerBlobURLHandleIfNecessary):
+ (WebCore::BlobURLHandle::unregisterBlobURLHandleIfNecessary):
+ (WebCore::BlobURLHandle::operator=):
+ (WebCore::BlobURLHandle::clear):
+ * fileapi/BlobURL.h:
+ (WebCore::BlobURLHandle::BlobURLHandle):
+ (WebCore::BlobURLHandle::url const):
+ * fileapi/ThreadableBlobRegistry.cpp:
+ (WebCore::ThreadableBlobRegistry::registerBlobURLHandle):
+ (WebCore::ThreadableBlobRegistry::unregisterBlobURLHandle):
+ * fileapi/ThreadableBlobRegistry.h:
+ * loader/PolicyChecker.cpp:
+ (WebCore::FrameLoader::PolicyChecker::extendBlobURLLifetimeIfNecessary const):
+ (WebCore::FrameLoader::PolicyChecker::checkNavigationPolicy):
+ (WebCore::FrameLoader::PolicyChecker::checkNewWindowPolicy):
+ * loader/PolicyChecker.h:
+ * platform/network/BlobRegistry.h:
+ * platform/network/BlobRegistryImpl.cpp:
+ (WebCore::BlobRegistryImpl::registerFileBlobURL):
+ (WebCore::BlobRegistryImpl::registerBlobURL):
+ (WebCore::BlobRegistryImpl::registerBlobURLOptionallyFileBacked):
+ (WebCore::BlobRegistryImpl::registerBlobURLForSlice):
+ (WebCore::BlobRegistryImpl::unregisterBlobURL):
+ (WebCore::BlobRegistryImpl::addBlobData):
+ (WebCore::BlobRegistryImpl::registerBlobURLHandle):
+ (WebCore::BlobRegistryImpl::unregisterBlobURLHandle):
+ * platform/network/BlobRegistryImpl.h:
+ * xml/XMLHttpRequest.cpp:
+ (WebCore::XMLHttpRequest::setResponseType):
+ (WebCore::XMLHttpRequest::open):
+ (WebCore::XMLHttpRequest::prepareToSend):
+ (WebCore::XMLHttpRequest::send):
+ (WebCore::XMLHttpRequest::createRequest):
+ (WebCore::XMLHttpRequest::clearRequest):
+ (WebCore::XMLHttpRequest::didFinishLoading):
+ * xml/XMLHttpRequest.h:
+
2021-08-09 Simon Fraser <[email protected]>
Vertical scroll with mouse wheel in horizontal scroller fails to propagate to the document
Modified: trunk/Source/WebCore/Headers.cmake (280823 => 280824)
--- trunk/Source/WebCore/Headers.cmake 2021-08-10 03:11:48 UTC (rev 280823)
+++ trunk/Source/WebCore/Headers.cmake 2021-08-10 03:33:03 UTC (rev 280824)
@@ -598,6 +598,7 @@
fileapi/AsyncFileStream.h
fileapi/Blob.h
fileapi/BlobPropertyBag.h
+ fileapi/BlobURL.h
fileapi/EndingType.h
fileapi/File.h
fileapi/FileList.h
Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (280823 => 280824)
--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2021-08-10 03:11:48 UTC (rev 280823)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2021-08-10 03:33:03 UTC (rev 280824)
@@ -3037,7 +3037,7 @@
97627B9814FB5424002CDCA1 /* Supplementable.h in Headers */ = {isa = PBXBuildFile; fileRef = 97627B9714FB5424002CDCA1 /* Supplementable.h */; settings = {ATTRIBUTES = (Private, ); }; };
976D6C79122B8A3D001FD1F7 /* Blob.h in Headers */ = {isa = PBXBuildFile; fileRef = 976D6C5A122B8A3D001FD1F7 /* Blob.h */; settings = {ATTRIBUTES = (Private, ); }; };
976D6C7C122B8A3D001FD1F7 /* BlobBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = 976D6C5D122B8A3D001FD1F7 /* BlobBuilder.h */; };
- 976D6C7F122B8A3D001FD1F7 /* BlobURL.h in Headers */ = {isa = PBXBuildFile; fileRef = 976D6C60122B8A3D001FD1F7 /* BlobURL.h */; };
+ 976D6C7F122B8A3D001FD1F7 /* BlobURL.h in Headers */ = {isa = PBXBuildFile; fileRef = 976D6C60122B8A3D001FD1F7 /* BlobURL.h */; settings = {ATTRIBUTES = (Private, ); }; };
976D6C81122B8A3D001FD1F7 /* File.h in Headers */ = {isa = PBXBuildFile; fileRef = 976D6C62122B8A3D001FD1F7 /* File.h */; settings = {ATTRIBUTES = (Private, ); }; };
976D6C86122B8A3D001FD1F7 /* FileList.h in Headers */ = {isa = PBXBuildFile; fileRef = 976D6C67122B8A3D001FD1F7 /* FileList.h */; settings = {ATTRIBUTES = (Private, ); }; };
976D6C89122B8A3D001FD1F7 /* FileReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 976D6C6A122B8A3D001FD1F7 /* FileReader.h */; };
Modified: trunk/Source/WebCore/bindings/js/SerializedScriptValue.cpp (280823 => 280824)
--- trunk/Source/WebCore/bindings/js/SerializedScriptValue.cpp 2021-08-10 03:11:48 UTC (rev 280823)
+++ trunk/Source/WebCore/bindings/js/SerializedScriptValue.cpp 2021-08-10 03:33:03 UTC (rev 280824)
@@ -600,7 +600,7 @@
WasmModuleArray& wasmModules,
WasmMemoryHandleArray& wasmMemoryHandles,
#endif
- Vector<Blob::Handle>& blobHandles, Vector<uint8_t>& out, SerializationContext context, ArrayBufferContentsArray& sharedBuffers)
+ Vector<BlobURLHandle>& blobHandles, Vector<uint8_t>& out, SerializationContext context, ArrayBufferContentsArray& sharedBuffers)
{
CloneSerializer serializer(lexicalGlobalObject, messagePorts, arrayBuffers, imageBitmaps,
#if ENABLE(OFFSCREEN_CANVAS_IN_WORKERS)
@@ -647,7 +647,7 @@
WasmModuleArray& wasmModules,
WasmMemoryHandleArray& wasmMemoryHandles,
#endif
- Vector<Blob::Handle>& blobHandles, Vector<uint8_t>& out, SerializationContext context, ArrayBufferContentsArray& sharedBuffers)
+ Vector<BlobURLHandle>& blobHandles, Vector<uint8_t>& out, SerializationContext context, ArrayBufferContentsArray& sharedBuffers)
: CloneBase(lexicalGlobalObject)
, m_buffer(out)
, m_blobHandles(blobHandles)
@@ -1297,7 +1297,7 @@
if (auto* key = JSCryptoKey::toWrapped(vm, obj)) {
write(CryptoKeyTag);
Vector<uint8_t> serializedKey;
- Vector<Blob::Handle> dummyBlobHandles;
+ Vector<BlobURLHandle> dummyBlobHandles;
Vector<RefPtr<MessagePort>> dummyMessagePorts;
Vector<RefPtr<JSC::ArrayBuffer>> dummyArrayBuffers;
#if ENABLE(WEBASSEMBLY)
@@ -1760,7 +1760,7 @@
}
Vector<uint8_t>& m_buffer;
- Vector<Blob::Handle>& m_blobHandles;
+ Vector<BlobURLHandle>& m_blobHandles;
ObjectPool m_objectPool;
ObjectPool m_transferredMessagePorts;
ObjectPool m_transferredArrayBuffers;
@@ -3915,7 +3915,7 @@
m_memoryCost = computeMemoryCost();
}
-SerializedScriptValue::SerializedScriptValue(Vector<uint8_t>&& buffer, const Vector<Blob::Handle>& blobHandles, std::unique_ptr<ArrayBufferContentsArray> arrayBufferContentsArray, std::unique_ptr<ArrayBufferContentsArray> sharedBufferContentsArray, Vector<std::optional<ImageBitmapBacking>>&& backingStores
+SerializedScriptValue::SerializedScriptValue(Vector<uint8_t>&& buffer, const Vector<BlobURLHandle>& blobHandles, std::unique_ptr<ArrayBufferContentsArray> arrayBufferContentsArray, std::unique_ptr<ArrayBufferContentsArray> sharedBufferContentsArray, Vector<std::optional<ImageBitmapBacking>>&& backingStores
#if ENABLE(OFFSCREEN_CANVAS_IN_WORKERS)
, Vector<std::unique_ptr<DetachedOffscreenCanvas>>&& detachedOffscreenCanvases
#endif
@@ -4065,7 +4065,7 @@
RefPtr<SerializedScriptValue> SerializedScriptValue::create(JSGlobalObject& lexicalGlobalObject, JSValue value, SerializationErrorMode throwExceptions)
{
Vector<uint8_t> buffer;
- Vector<Blob::Handle> blobHandles;
+ Vector<BlobURLHandle> blobHandles;
Vector<RefPtr<MessagePort>> dummyMessagePorts;
Vector<RefPtr<ImageBitmap>> dummyImageBitmaps;
#if ENABLE(OFFSCREEN_CANVAS_IN_WORKERS)
@@ -4217,7 +4217,7 @@
#endif
Vector<uint8_t> buffer;
- Vector<Blob::Handle> blobHandles;
+ Vector<BlobURLHandle> blobHandles;
#if ENABLE(WEBASSEMBLY)
WasmModuleArray wasmModules;
WasmMemoryHandleArray wasmMemoryHandles;
Modified: trunk/Source/WebCore/bindings/js/SerializedScriptValue.h (280823 => 280824)
--- trunk/Source/WebCore/bindings/js/SerializedScriptValue.h 2021-08-10 03:11:48 UTC (rev 280823)
+++ trunk/Source/WebCore/bindings/js/SerializedScriptValue.h 2021-08-10 03:33:03 UTC (rev 280824)
@@ -99,7 +99,7 @@
bool hasBlobURLs() const { return !m_blobHandles.isEmpty(); }
Vector<String> blobURLs() const;
- const Vector<Blob::Handle>& blobHandles() const { return m_blobHandles; }
+ const Vector<BlobURLHandle>& blobHandles() const { return m_blobHandles; }
void writeBlobsToDiskForIndexedDB(CompletionHandler<void(IDBValue&&)>&&);
IDBValue writeBlobsToDiskForIndexedDBSynchronously();
static Ref<SerializedScriptValue> createFromWireBytes(Vector<uint8_t>&& data)
@@ -123,7 +123,7 @@
#endif
);
- SerializedScriptValue(Vector<unsigned char>&&, const Vector<Blob::Handle>& blobHandles, std::unique_ptr<ArrayBufferContentsArray>, std::unique_ptr<ArrayBufferContentsArray> sharedBuffers, Vector<std::optional<ImageBitmapBacking>>&& backingStores
+ SerializedScriptValue(Vector<unsigned char>&&, const Vector<BlobURLHandle>& blobHandles, std::unique_ptr<ArrayBufferContentsArray>, std::unique_ptr<ArrayBufferContentsArray> sharedBuffers, Vector<std::optional<ImageBitmapBacking>>&& backingStores
#if ENABLE(OFFSCREEN_CANVAS_IN_WORKERS)
, Vector<std::unique_ptr<DetachedOffscreenCanvas>>&& = { }
#endif
@@ -152,7 +152,7 @@
std::unique_ptr<WasmModuleArray> m_wasmModulesArray;
std::unique_ptr<WasmMemoryHandleArray> m_wasmMemoryHandlesArray;
#endif
- Vector<Blob::Handle> m_blobHandles;
+ Vector<BlobURLHandle> m_blobHandles;
size_t m_memoryCost { 0 };
};
Modified: trunk/Source/WebCore/fileapi/Blob.cpp (280823 => 280824)
--- trunk/Source/WebCore/fileapi/Blob.cpp 2021-08-10 03:11:48 UTC (rev 280823)
+++ trunk/Source/WebCore/fileapi/Blob.cpp 2021-08-10 03:33:03 UTC (rev 280824)
@@ -76,67 +76,10 @@
return instance;
}
-// Unregisters the Blob's internal URL upon destruction. This can be used to extend the lifetime of the Blob data
-// without actually keeping the Blob object alive.
-class BlobInternalURL : public ThreadSafeRefCounted<BlobInternalURL> {
-public:
- static Ref<BlobInternalURL> create(Vector<BlobPart>&& blobParts, const String& contentType)
- {
- return adoptRef(*new BlobInternalURL(WTFMove(blobParts), contentType));
- }
-
- static Ref<BlobInternalURL> createForDeserialization(const URL& sourceURL, const String& fileBackedPath, const String& type)
- {
- return adoptRef(*new BlobInternalURL(sourceURL, fileBackedPath, type));
- }
-
- static Ref<BlobInternalURL> createForSlice(const URL& sourceURL, long long start, long long end, const String& type)
- {
- return adoptRef(*new BlobInternalURL(sourceURL, start, end, type));
- }
-
- static Ref<BlobInternalURL> adoptInternalURL(const URL& url)
- {
- return adoptRef(*new BlobInternalURL(crossThreadCopy(url)));
- }
-
- ~BlobInternalURL()
- {
- ThreadableBlobRegistry::unregisterBlobURL(m_internalURL);
- }
-
- URL url() const { return m_internalURL.isolatedCopy(); }
-
-private:
- BlobInternalURL(Vector<BlobPart>&& blobParts, const String& contentType)
- : m_internalURL(BlobURL::createInternalURL())
- {
- ThreadableBlobRegistry::registerBlobURL(m_internalURL, WTFMove(blobParts), contentType);
- }
- BlobInternalURL(const URL& sourceURL, long long start, long long end, const String& type)
- : m_internalURL(BlobURL::createInternalURL())
- {
- ThreadableBlobRegistry::registerBlobURLForSlice(m_internalURL, sourceURL, start, end, type);
- }
- BlobInternalURL(const URL& sourceURL, const String& fileBackedPath, const String& type)
- : m_internalURL(BlobURL::createInternalURL())
- {
- if (fileBackedPath.isEmpty())
- ThreadableBlobRegistry::registerBlobURL(nullptr, m_internalURL, sourceURL);
- else
- ThreadableBlobRegistry::registerBlobURLOptionallyFileBacked(m_internalURL, sourceURL, fileBackedPath, type);
- }
- BlobInternalURL(URL&& internalURL)
- : m_internalURL(WTFMove(internalURL))
- { }
-
- URL m_internalURL;
-};
-
Blob::Blob(UninitializedContructor, ScriptExecutionContext* context, URL&& url, String&& type)
: ActiveDOMObject(context)
, m_type(WTFMove(type))
- , m_internalURL(BlobInternalURL::adoptInternalURL(url))
+ , m_internalURL(WTFMove(url))
{
}
@@ -143,8 +86,9 @@
Blob::Blob(ScriptExecutionContext* context)
: ActiveDOMObject(context)
, m_size(0)
- , m_internalURL(BlobInternalURL::create({ }, { }))
+ , m_internalURL(BlobURL::createInternalURL())
{
+ ThreadableBlobRegistry::registerBlobURL(m_internalURL, { }, { });
}
static Vector<BlobPart> buildBlobData(Vector<BlobPartVariant>&& blobPartVariants, const BlobPropertyBag& propertyBag)
@@ -163,8 +107,9 @@
Blob::Blob(ScriptExecutionContext& context, Vector<BlobPartVariant>&& blobPartVariants, const BlobPropertyBag& propertyBag)
: ActiveDOMObject(&context)
, m_type(normalizedContentType(propertyBag.type))
- , m_internalURL(BlobInternalURL::create(buildBlobData(WTFMove(blobPartVariants), propertyBag), m_type))
+ , m_internalURL(BlobURL::createInternalURL())
{
+ ThreadableBlobRegistry::registerBlobURL(m_internalURL, buildBlobData(WTFMove(blobPartVariants), propertyBag), m_type);
}
Blob::Blob(ScriptExecutionContext* context, Vector<uint8_t>&& data, const String& contentType)
@@ -171,8 +116,9 @@
: ActiveDOMObject(context)
, m_type(contentType)
, m_size(data.size())
- , m_internalURL(BlobInternalURL::create({ BlobPart(WTFMove(data)) }, contentType))
+ , m_internalURL(BlobURL::createInternalURL())
{
+ ThreadableBlobRegistry::registerBlobURL(m_internalURL, { BlobPart(WTFMove(data)) }, contentType);
}
Blob::Blob(ReferencingExistingBlobConstructor, ScriptExecutionContext* context, const Blob& blob)
@@ -179,8 +125,9 @@
: ActiveDOMObject(context)
, m_type(blob.type())
, m_size(blob.size())
- , m_internalURL(BlobInternalURL::create({ BlobPart(blob.url()) } , m_type))
+ , m_internalURL(BlobURL::createInternalURL())
{
+ ThreadableBlobRegistry::registerBlobURL(m_internalURL, { BlobPart(blob.url()) } , m_type);
}
Blob::Blob(DeserializationContructor, ScriptExecutionContext* context, const URL& srcURL, const String& type, std::optional<unsigned long long> size, const String& fileBackedPath)
@@ -187,16 +134,21 @@
: ActiveDOMObject(context)
, m_type(normalizedContentType(type))
, m_size(size)
- , m_internalURL(BlobInternalURL::createForDeserialization(srcURL, fileBackedPath, m_type))
+ , m_internalURL(BlobURL::createInternalURL())
{
+ if (fileBackedPath.isEmpty())
+ ThreadableBlobRegistry::registerBlobURL(nullptr, m_internalURL, srcURL);
+ else
+ ThreadableBlobRegistry::registerBlobURLOptionallyFileBacked(m_internalURL, srcURL, fileBackedPath, m_type);
}
Blob::Blob(ScriptExecutionContext* context, const URL& srcURL, long long start, long long end, const String& type)
: ActiveDOMObject(context)
, m_type(normalizedContentType(type))
- , m_internalURL(BlobInternalURL::createForSlice(srcURL, start, end, m_type))
+ , m_internalURL(BlobURL::createInternalURL())
// m_size is not necessarily equal to end - start so we do not initialize it here.
{
+ ThreadableBlobRegistry::registerBlobURLForSlice(m_internalURL, srcURL, start, end, m_type);
}
Blob::~Blob()
@@ -205,14 +157,9 @@
(*m_blobLoaders.begin())->cancel();
}
-URL Blob::url() const
-{
- return m_internalURL->url();
-}
-
Ref<Blob> Blob::slice(ScriptExecutionContext& context, long long start, long long end, const String& contentType) const
{
- auto blob = adoptRef(*new Blob(&context, m_internalURL->url(), start, end, contentType));
+ auto blob = adoptRef(*new Blob(&context, m_internalURL, start, end, contentType));
blob->suspendIfNeeded();
return blob;
}
@@ -222,7 +169,7 @@
if (!m_size) {
// FIXME: _javascript_ cannot represent sizes as large as unsigned long long, we need to
// come up with an exception to throw if file size is not representable.
- unsigned long long actualSize = ThreadableBlobRegistry::blobSize(m_internalURL->url());
+ unsigned long long actualSize = ThreadableBlobRegistry::blobSize(m_internalURL);
m_size = isInBounds<long long>(actualSize) ? actualSize : 0;
}
@@ -395,23 +342,9 @@
return "Blob";
}
-Blob::Handle Blob::handle() const
+BlobURLHandle Blob::handle() const
{
- return Handle { m_internalURL.copyRef() };
+ return BlobURLHandle { m_internalURL };
}
-Blob::Handle::Handle(Ref<BlobInternalURL>&& internalURL)
- : m_internalURL(WTFMove(internalURL))
-{ }
-
-Blob::Handle::~Handle() = default;
-
-Blob::Handle::Handle(Handle&&) = default;
-Blob::Handle::Handle(const Handle&) = default;
-
-URL Blob::Handle::url() const
-{
- return m_internalURL->url();
-}
-
} // namespace WebCore
Modified: trunk/Source/WebCore/fileapi/Blob.h (280823 => 280824)
--- trunk/Source/WebCore/fileapi/Blob.h 2021-08-10 03:11:48 UTC (rev 280823)
+++ trunk/Source/WebCore/fileapi/Blob.h 2021-08-10 03:33:03 UTC (rev 280824)
@@ -32,6 +32,7 @@
#pragma once
#include "BlobPropertyBag.h"
+#include "BlobURL.h"
#include "FileReaderLoader.h"
#include "ScriptExecutionContext.h"
#include "ScriptWrappable.h"
@@ -57,7 +58,6 @@
template<typename> class ExceptionOr;
using BlobPartVariant = Variant<RefPtr<JSC::ArrayBufferView>, RefPtr<JSC::ArrayBuffer>, RefPtr<Blob>, String>;
-class BlobInternalURL;
class Blob : public ScriptWrappable, public URLRegistrable, public RefCounted<Blob>, public ActiveDOMObject {
WTF_MAKE_ISO_ALLOCATED_EXPORT(Blob, WEBCORE_EXPORT);
@@ -93,7 +93,7 @@
virtual ~Blob();
- WEBCORE_EXPORT URL url() const;
+ URL url() const { return m_internalURL; }
const String& type() const { return m_type; }
WEBCORE_EXPORT unsigned long long size() const;
@@ -117,19 +117,8 @@
void arrayBuffer(ScriptExecutionContext&, Ref<DeferredPromise>&&);
ExceptionOr<Ref<ReadableStream>> stream(ScriptExecutionContext&);
- class Handle {
- public:
- explicit Handle(Ref<BlobInternalURL>&&);
- ~Handle();
- Handle(Handle&&);
- Handle(const Handle&);
- URL url() const;
- private:
- Ref<BlobInternalURL> m_internalURL;
- };
-
// Keeping the handle alive will keep the Blob data alive (but not the Blob object).
- Handle handle() const;
+ BlobURLHandle handle() const;
protected:
WEBCORE_EXPORT explicit Blob(ScriptExecutionContext*);
@@ -160,7 +149,7 @@
// This is an internal URL referring to the blob data associated with this object. It serves
// as an identifier for this blob. The internal URL is never used to source the blob's content
// into an HTML or for FileRead'ing, public blob URLs must be used for those purposes.
- Ref<BlobInternalURL> m_internalURL;
+ URL m_internalURL;
HashSet<std::unique_ptr<BlobLoader>> m_blobLoaders;
};
Modified: trunk/Source/WebCore/fileapi/BlobURL.cpp (280823 => 280824)
--- trunk/Source/WebCore/fileapi/BlobURL.cpp 2021-08-10 03:11:48 UTC (rev 280823)
+++ trunk/Source/WebCore/fileapi/BlobURL.cpp 2021-08-10 03:33:03 UTC (rev 280824)
@@ -96,45 +96,67 @@
return URL({ }, urlString);
}
-URLWithBlobURLLifetimeExtension::URLWithBlobURLLifetimeExtension(const URL& url)
- : m_url(url)
+BlobURLHandle::BlobURLHandle(const BlobURLHandle& other)
+ : m_url(other.m_url.isolatedCopy())
{
- extendBlobURLLifetimeIfNecessary();
+ registerBlobURLHandleIfNecessary();
}
-URLWithBlobURLLifetimeExtension::~URLWithBlobURLLifetimeExtension()
+BlobURLHandle::BlobURLHandle(const URL& url)
+ : m_url(url.isolatedCopy())
{
- unregisterCurrentURLIfNecessary();
+ ASSERT(m_url.protocolIsBlob());
+ registerBlobURLHandleIfNecessary();
}
-void URLWithBlobURLLifetimeExtension::extendBlobURLLifetimeIfNecessary()
+BlobURLHandle::~BlobURLHandle()
{
- 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);
- }
+ unregisterBlobURLHandleIfNecessary();
}
-void URLWithBlobURLLifetimeExtension::unregisterCurrentURLIfNecessary()
+void BlobURLHandle::registerBlobURLHandleIfNecessary()
{
if (m_url.protocolIsBlob())
- ThreadableBlobRegistry::unregisterBlobURL(m_url);
+ ThreadableBlobRegistry::registerBlobURLHandle(m_url);
}
-URLWithBlobURLLifetimeExtension& URLWithBlobURLLifetimeExtension::operator=(URLWithBlobURLLifetimeExtension&& other)
+void BlobURLHandle::unregisterBlobURLHandleIfNecessary()
{
- unregisterCurrentURLIfNecessary();
+ if (m_url.protocolIsBlob())
+ ThreadableBlobRegistry::unregisterBlobURLHandle(m_url);
+}
+
+BlobURLHandle& BlobURLHandle::operator=(const BlobURLHandle& other)
+{
+ if (this == &other)
+ return *this;
+
+ unregisterBlobURLHandleIfNecessary();
+ m_url = other.m_url.isolatedCopy();
+ registerBlobURLHandleIfNecessary();
+
+ return *this;
+}
+
+void BlobURLHandle::clear()
+{
+ unregisterBlobURLHandleIfNecessary();
+ m_url = { };
+}
+
+BlobURLHandle& BlobURLHandle::operator=(BlobURLHandle&& other)
+{
+ unregisterBlobURLHandleIfNecessary();
m_url = std::exchange(other.m_url, { });
return *this;
}
-URLWithBlobURLLifetimeExtension& URLWithBlobURLLifetimeExtension::operator=(URL&& url)
+BlobURLHandle& BlobURLHandle::operator=(const URL& url)
{
- unregisterCurrentURLIfNecessary();
- m_url = WTFMove(url);
- extendBlobURLLifetimeIfNecessary();
+ ASSERT(url.protocolIsBlob());
+ unregisterBlobURLHandleIfNecessary();
+ m_url = url.isolatedCopy();
+ registerBlobURLHandleIfNecessary();
return *this;
}
Modified: trunk/Source/WebCore/fileapi/BlobURL.h (280823 => 280824)
--- trunk/Source/WebCore/fileapi/BlobURL.h 2021-08-10 03:11:48 UTC (rev 280823)
+++ trunk/Source/WebCore/fileapi/BlobURL.h 2021-08-10 03:33:03 UTC (rev 280824)
@@ -58,27 +58,31 @@
BlobURL() { }
};
-class URLWithBlobURLLifetimeExtension {
+// Extends the lifetime of the Blob URL. This means that the blob URL will remain valid after
+// revokeObjectURL() has been called, as long as BlobURLHandle objects refer to the blob URL.
+class BlobURLHandle {
WTF_MAKE_FAST_ALLOCATED;
- WTF_MAKE_NONCOPYABLE(URLWithBlobURLLifetimeExtension);
public:
- URLWithBlobURLLifetimeExtension() = default;
- explicit URLWithBlobURLLifetimeExtension(const URL&);
- ~URLWithBlobURLLifetimeExtension();
+ BlobURLHandle() = default;
+ explicit BlobURLHandle(const URL&);
+ ~BlobURLHandle();
- URLWithBlobURLLifetimeExtension(URLWithBlobURLLifetimeExtension&& other)
+ BlobURLHandle(const BlobURLHandle&);
+ BlobURLHandle(BlobURLHandle&& other)
: m_url(std::exchange(other.m_url, { }))
{ }
- URLWithBlobURLLifetimeExtension& operator=(URLWithBlobURLLifetimeExtension&&);
- URLWithBlobURLLifetimeExtension& operator=(URL&&);
+ BlobURLHandle& operator=(const BlobURLHandle&);
+ BlobURLHandle& operator=(BlobURLHandle&&);
+ BlobURLHandle& operator=(const URL&);
- operator const URL&() const { return m_url; }
- const URL& url() const { return m_url; }
+ URL url() const { return m_url.isolatedCopy(); }
+ void clear();
+
private:
- void unregisterCurrentURLIfNecessary();
- void extendBlobURLLifetimeIfNecessary();
+ void unregisterBlobURLHandleIfNecessary();
+ void registerBlobURLHandleIfNecessary();
URL m_url;
};
Modified: trunk/Source/WebCore/fileapi/ThreadableBlobRegistry.cpp (280823 => 280824)
--- trunk/Source/WebCore/fileapi/ThreadableBlobRegistry.cpp 2021-08-10 03:11:48 UTC (rev 280823)
+++ trunk/Source/WebCore/fileapi/ThreadableBlobRegistry.cpp 2021-08-10 03:33:03 UTC (rev 280824)
@@ -155,15 +155,25 @@
if (isBlobURLContainsNullOrigin(url))
originMap()->remove(url.string());
- if (isMainThread()) {
+ ensureOnMainThread([url = "" {
blobRegistry().unregisterBlobURL(url);
- return;
- }
- callOnMainThread([url = "" {
- blobRegistry().unregisterBlobURL(url);
});
}
+void ThreadableBlobRegistry::registerBlobURLHandle(const URL& url)
+{
+ ensureOnMainThread([url = "" {
+ blobRegistry().registerBlobURLHandle(url);
+ });
+}
+
+void ThreadableBlobRegistry::unregisterBlobURLHandle(const URL& url)
+{
+ ensureOnMainThread([url = "" {
+ blobRegistry().unregisterBlobURLHandle(url);
+ });
+}
+
RefPtr<SecurityOrigin> ThreadableBlobRegistry::getCachedOrigin(const URL& url)
{
if (auto cachedOrigin = originMap()->get(url.string()))
Modified: trunk/Source/WebCore/fileapi/ThreadableBlobRegistry.h (280823 => 280824)
--- trunk/Source/WebCore/fileapi/ThreadableBlobRegistry.h 2021-08-10 03:11:48 UTC (rev 280823)
+++ trunk/Source/WebCore/fileapi/ThreadableBlobRegistry.h 2021-08-10 03:33:03 UTC (rev 280824)
@@ -47,6 +47,9 @@
static void registerBlobURLForSlice(const URL& newURL, const URL& srcURL, long long start, long long end, const String& contentType);
static void unregisterBlobURL(const URL&);
+ static void registerBlobURLHandle(const URL&);
+ static void unregisterBlobURLHandle(const URL&);
+
static unsigned long long blobSize(const URL&);
// Returns the origin for the given blob URL. This is because we are not able to embed the unique security origin or the origin of file URL
Modified: trunk/Source/WebCore/loader/PolicyChecker.cpp (280823 => 280824)
--- trunk/Source/WebCore/loader/PolicyChecker.cpp 2021-08-10 03:11:48 UTC (rev 280823)
+++ trunk/Source/WebCore/loader/PolicyChecker.cpp 2021-08-10 03:33:03 UTC (rev 280824)
@@ -104,17 +104,12 @@
checkNavigationPolicy(WTFMove(newRequest), redirectResponse, m_frame.loader().activeDocumentLoader(), { }, WTFMove(function));
}
-URLWithBlobURLLifetimeExtension FrameLoader::PolicyChecker::extendBlobURLLifetimeIfNecessary(ResourceRequest& request, DocumentLoader* loader, PolicyDecisionMode mode) const
+BlobURLHandle FrameLoader::PolicyChecker::extendBlobURLLifetimeIfNecessary(const ResourceRequest& request, PolicyDecisionMode mode) const
{
if (mode != PolicyDecisionMode::Asynchronous || !request.url().protocolIsBlob())
return { };
- URLWithBlobURLLifetimeExtension urlWithLifetimeExtension(request.url());
- request.setURL(urlWithLifetimeExtension);
- if (loader)
- loader->request().setURL(urlWithLifetimeExtension);
-
- return urlWithLifetimeExtension;
+ return BlobURLHandle { request.url() };
}
void FrameLoader::PolicyChecker::checkNavigationPolicy(ResourceRequest&& request, const ResourceResponse& redirectResponse, DocumentLoader* loader, RefPtr<FormState>&& formState, NavigationPolicyDecisionFunction&& function, PolicyDecisionMode policyDecisionMode)
@@ -197,7 +192,7 @@
m_frame.loader().clearProvisionalLoadForPolicyCheck();
- auto blobURLLifetimeExtension = extendBlobURLLifetimeIfNecessary(request, loader, policyDecisionMode);
+ auto blobURLLifetimeExtension = extendBlobURLLifetimeIfNecessary(request, policyDecisionMode);
bool isInitialEmptyDocumentLoad = !m_frame.loader().stateMachine().committedFirstRealDocumentLoad() && request.url().protocolIsAbout() && !substituteData.isValid();
auto requestIdentifier = PolicyCheckIdentifier::create();
@@ -255,7 +250,7 @@
if (!DOMWindow::allowPopUp(m_frame))
return function({ }, nullptr, { }, { }, ShouldContinuePolicyCheck::No);
- auto blobURLLifetimeExtension = extendBlobURLLifetimeIfNecessary(request, nullptr);
+ auto blobURLLifetimeExtension = extendBlobURLLifetimeIfNecessary(request);
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 (280823 => 280824)
--- trunk/Source/WebCore/loader/PolicyChecker.h 2021-08-10 03:11:48 UTC (rev 280823)
+++ trunk/Source/WebCore/loader/PolicyChecker.h 2021-08-10 03:33:03 UTC (rev 280824)
@@ -51,7 +51,7 @@
class NavigationAction;
class ResourceError;
class ResourceResponse;
-class URLWithBlobURLLifetimeExtension;
+class BlobURLHandle;
enum class NavigationPolicyDecision : uint8_t {
ContinueLoad,
@@ -90,7 +90,7 @@
private:
void handleUnimplementablePolicy(const ResourceError&);
- URLWithBlobURLLifetimeExtension extendBlobURLLifetimeIfNecessary(ResourceRequest&, DocumentLoader*, PolicyDecisionMode = PolicyDecisionMode::Asynchronous) const;
+ BlobURLHandle extendBlobURLLifetimeIfNecessary(const ResourceRequest&, PolicyDecisionMode = PolicyDecisionMode::Asynchronous) const;
Frame& m_frame;
Modified: trunk/Source/WebCore/platform/network/BlobRegistry.h (280823 => 280824)
--- trunk/Source/WebCore/platform/network/BlobRegistry.h 2021-08-10 03:11:48 UTC (rev 280823)
+++ trunk/Source/WebCore/platform/network/BlobRegistry.h 2021-08-10 03:33:03 UTC (rev 280824)
@@ -63,6 +63,9 @@
virtual void unregisterBlobURL(const URL&) = 0;
+ virtual void registerBlobURLHandle(const URL&) = 0;
+ virtual void unregisterBlobURLHandle(const URL&) = 0;
+
virtual unsigned long long blobSize(const URL&) = 0;
virtual void writeBlobsToTemporaryFiles(const Vector<String>& blobURLs, CompletionHandler<void(Vector<String>&& filePaths)>&&) = 0;
Modified: trunk/Source/WebCore/platform/network/BlobRegistryImpl.cpp (280823 => 280824)
--- trunk/Source/WebCore/platform/network/BlobRegistryImpl.cpp 2021-08-10 03:11:48 UTC (rev 280823)
+++ trunk/Source/WebCore/platform/network/BlobRegistryImpl.cpp 2021-08-10 03:33:03 UTC (rev 280824)
@@ -115,7 +115,7 @@
auto blobData = BlobData::create(contentType);
blobData->appendFile(WTFMove(file));
- m_blobs.set(url.string(), WTFMove(blobData));
+ addBlobData(url.string(), WTFMove(blobData));
}
void BlobRegistryImpl::registerBlobURL(const URL& url, Vector<BlobPart>&& blobParts, const String& contentType)
@@ -149,7 +149,7 @@
}
}
- m_blobs.set(url.string(), WTFMove(blobData));
+ addBlobData(url.string(), WTFMove(blobData));
}
void BlobRegistryImpl::registerBlobURL(const URL& url, const URL& srcURL)
@@ -164,7 +164,7 @@
BlobData* src = ""
if (src) {
- m_blobs.set(url.string(), src);
+ addBlobData(url.string(), src);
return;
}
@@ -174,7 +174,7 @@
auto backingFile = BlobData::create(contentType);
backingFile->appendFile(file.releaseNonNull());
- m_blobs.set(url.string(), WTFMove(backingFile));
+ addBlobData(url.string(), WTFMove(backingFile));
}
void BlobRegistryImpl::registerBlobURLForSlice(const URL& url, const URL& srcURL, long long start, long long end, const String& contentType)
@@ -210,13 +210,14 @@
appendStorageItems(newData.ptr(), originalData->items(), start, newLength);
- m_blobs.set(url.string(), WTFMove(newData));
+ addBlobData(url.string(), WTFMove(newData));
}
void BlobRegistryImpl::unregisterBlobURL(const URL& url)
{
ASSERT(isMainThread());
- m_blobs.remove(url.string());
+ if (m_blobReferences.remove(url.string()))
+ m_blobs.remove(url.string());
}
BlobData* BlobRegistryImpl::getBlobDataFromURL(const URL& url) const
@@ -359,4 +360,23 @@
return result;
}
+void BlobRegistryImpl::addBlobData(const String& url, RefPtr<BlobData>&& blobData)
+{
+ auto addResult = m_blobs.set(url, WTFMove(blobData));
+ if (addResult.isNewEntry)
+ m_blobReferences.add(url);
+}
+
+void BlobRegistryImpl::registerBlobURLHandle(const URL& url)
+{
+ if (m_blobs.contains(url.string()))
+ m_blobReferences.add(url.string());
+}
+
+void BlobRegistryImpl::unregisterBlobURLHandle(const URL& url)
+{
+ if (m_blobReferences.remove(url.string()))
+ m_blobs.remove(url.string());
+}
+
} // namespace WebCore
Modified: trunk/Source/WebCore/platform/network/BlobRegistryImpl.h (280823 => 280824)
--- trunk/Source/WebCore/platform/network/BlobRegistryImpl.h 2021-08-10 03:11:48 UTC (rev 280823)
+++ trunk/Source/WebCore/platform/network/BlobRegistryImpl.h 2021-08-10 03:33:03 UTC (rev 280824)
@@ -33,6 +33,7 @@
#include "BlobData.h"
#include "BlobRegistry.h"
+#include <wtf/HashCountedSet.h>
#include <wtf/HashMap.h>
#include <wtf/URLHash.h>
#include <wtf/text/StringHash.h>
@@ -65,6 +66,9 @@
void registerBlobURLForSlice(const URL&, const URL& srcURL, long long start, long long end, const String& contentType);
void unregisterBlobURL(const URL&);
+ void registerBlobURLHandle(const URL&);
+ void unregisterBlobURLHandle(const URL&);
+
unsigned long long blobSize(const URL&);
void writeBlobsToTemporaryFiles(const Vector<String>& blobURLs, CompletionHandler<void(Vector<String>&& filePaths)>&&);
@@ -78,6 +82,9 @@
Vector<RefPtr<BlobDataFileReference>> filesInBlob(const URL&) const;
private:
+ void addBlobData(const String& url, RefPtr<BlobData>&&);
+
+ HashCountedSet<String> m_blobReferences;
HashMap<String, RefPtr<BlobData>> m_blobs;
};
Modified: trunk/Source/WebCore/xml/XMLHttpRequest.cpp (280823 => 280824)
--- trunk/Source/WebCore/xml/XMLHttpRequest.cpp 2021-08-10 03:11:48 UTC (rev 280823)
+++ trunk/Source/WebCore/xml/XMLHttpRequest.cpp 2021-08-10 03:33:03 UTC (rev 280824)
@@ -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.url().protocolIsInHTTPFamily()) {
+ if (!m_async && scriptExecutionContext()->isDocument() && m_url.protocolIsInHTTPFamily()) {
logConsoleError(scriptExecutionContext(), "XMLHttpRequest.responseType cannot be changed for synchronous HTTP(S) requests made from the window context.");
return Exception { InvalidAccessError };
}
@@ -382,9 +382,10 @@
clearResponse();
clearRequest();
- auto upgradedURL = url;
- context->contentSecurityPolicy()->upgradeInsecureRequestIfNeeded(upgradedURL, ContentSecurityPolicy::InsecureRequestType::Load);
- m_url = WTFMove(upgradedURL);
+ m_url = url;
+ context->contentSecurityPolicy()->upgradeInsecureRequestIfNeeded(m_url, ContentSecurityPolicy::InsecureRequestType::Load);
+ if (m_url.protocolIsBlob())
+ m_blobURLLifetimeExtension = m_url;
m_async = async;
@@ -417,7 +418,7 @@
auto& context = *scriptExecutionContext();
if (is<Document>(context) && downcast<Document>(context).shouldIgnoreSyncXHRs()) {
- logConsoleError(scriptExecutionContext(), makeString("Ignoring XMLHttpRequest.send() call for '", m_url.url().string(), "' because the maximum number of synchronous failures was reached."));
+ logConsoleError(scriptExecutionContext(), makeString("Ignoring XMLHttpRequest.send() call for '", m_url.string(), "' because the maximum number of synchronous failures was reached."));
return ExceptionOr<void> { };
}
@@ -521,7 +522,7 @@
return WTFMove(result.value());
if (m_method != "GET" && m_method != "HEAD") {
- if (!m_url.url().protocolIsInHTTPFamily()) {
+ if (!m_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.
@@ -594,8 +595,10 @@
ExceptionOr<void> XMLHttpRequest::createRequest()
{
// Only GET request is supported for blob URL.
- if (!m_async && m_url.url().protocolIsBlob() && m_method != "GET")
+ if (!m_async && m_url.protocolIsBlob() && m_method != "GET") {
+ m_blobURLLifetimeExtension.clear();
return Exception { NetworkError };
+ }
if (m_async && m_upload && m_upload->hasEventListeners())
m_uploadListenerFlag = true;
@@ -747,6 +750,7 @@
m_requestHeaders.clear();
m_requestEntityBody = nullptr;
m_url = URL { };
+ m_blobURLLifetimeExtension.clear();
}
void XMLHttpRequest::genericError()
@@ -939,6 +943,7 @@
m_loadingActivity = std::nullopt;
m_url = URL { };
+ m_blobURLLifetimeExtension.clear();
m_sendFlag = false;
changeState(DONE);
Modified: trunk/Source/WebCore/xml/XMLHttpRequest.h (280823 => 280824)
--- trunk/Source/WebCore/xml/XMLHttpRequest.h 2021-08-10 03:11:48 UTC (rev 280823)
+++ trunk/Source/WebCore/xml/XMLHttpRequest.h 2021-08-10 03:33:03 UTC (rev 280824)
@@ -216,7 +216,8 @@
std::unique_ptr<XMLHttpRequestUpload> m_upload;
- URLWithBlobURLLifetimeExtension m_url;
+ URL m_url;
+ BlobURLHandle m_blobURLLifetimeExtension;
String m_method;
HTTPHeaderMap m_requestHeaders;
RefPtr<FormData> m_requestEntityBody;
Modified: trunk/Source/WebKit/ChangeLog (280823 => 280824)
--- trunk/Source/WebKit/ChangeLog 2021-08-10 03:11:48 UTC (rev 280823)
+++ trunk/Source/WebKit/ChangeLog 2021-08-10 03:33:03 UTC (rev 280824)
@@ -1,3 +1,22 @@
+2021-08-09 Chris Dumez <[email protected]>
+
+ Blob URL changes after loading it
+ https://bugs.webkit.org/show_bug.cgi?id=228923
+
+ Reviewed by Geoff Garen.
+
+ * NetworkProcess/NetworkConnectionToWebProcess.cpp:
+ (WebKit::NetworkConnectionToWebProcess::registerBlobURLHandle):
+ (WebKit::NetworkConnectionToWebProcess::unregisterBlobURLHandle):
+ * NetworkProcess/NetworkConnectionToWebProcess.h:
+ * NetworkProcess/NetworkConnectionToWebProcess.messages.in:
+ * NetworkProcess/NetworkProcessPlatformStrategies.cpp:
+ (WebKit::NetworkProcessPlatformStrategies::createBlobRegistry):
+ * WebProcess/FileAPI/BlobRegistryProxy.cpp:
+ (WebKit::BlobRegistryProxy::registerBlobURLHandle):
+ (WebKit::BlobRegistryProxy::unregisterBlobURLHandle):
+ * WebProcess/FileAPI/BlobRegistryProxy.h:
+
2021-08-09 Myles C. Maxfield <[email protected]>
Create a Language log channel
Modified: trunk/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.cpp (280823 => 280824)
--- trunk/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.cpp 2021-08-10 03:11:48 UTC (rev 280823)
+++ trunk/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.cpp 2021-08-10 03:33:03 UTC (rev 280824)
@@ -866,6 +866,24 @@
session->blobRegistry().unregisterBlobURL(url);
}
+void NetworkConnectionToWebProcess::registerBlobURLHandle(const URL& url)
+{
+ auto* session = networkSession();
+ if (!session)
+ return;
+
+ session->blobRegistry().registerBlobURLHandle(url);
+}
+
+void NetworkConnectionToWebProcess::unregisterBlobURLHandle(const URL& url)
+{
+ auto* session = networkSession();
+ if (!session)
+ return;
+
+ session->blobRegistry().unregisterBlobURLHandle(url);
+}
+
void NetworkConnectionToWebProcess::blobSize(const URL& url, CompletionHandler<void(uint64_t)>&& completionHandler)
{
auto* session = networkSession();
Modified: trunk/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.h (280823 => 280824)
--- trunk/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.h 2021-08-10 03:11:48 UTC (rev 280823)
+++ trunk/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.h 2021-08-10 03:33:03 UTC (rev 280824)
@@ -236,6 +236,9 @@
void unregisterBlobURL(const URL&);
void writeBlobsToTemporaryFiles(const Vector<String>& blobURLs, CompletionHandler<void(Vector<String>&&)>&&);
+ void registerBlobURLHandle(const URL&);
+ void unregisterBlobURLHandle(const URL&);
+
void setCaptureExtraNetworkLoadMetricsEnabled(bool);
void createSocketStream(URL&&, String cachePartition, WebCore::WebSocketIdentifier);
Modified: trunk/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.messages.in (280823 => 280824)
--- trunk/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.messages.in 2021-08-10 03:11:48 UTC (rev 280823)
+++ trunk/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.messages.in 2021-08-10 03:33:03 UTC (rev 280824)
@@ -56,6 +56,8 @@
UnregisterBlobURL(URL url)
BlobSize(URL url) -> (uint64_t resultSize) Synchronous
WriteBlobsToTemporaryFiles(Vector<String> blobURLs) -> (Vector<String> fileNames) Async
+ RegisterBlobURLHandle(URL url);
+ UnregisterBlobURLHandle(URL url);
SetCaptureExtraNetworkLoadMetricsEnabled(bool enabled)
Modified: trunk/Source/WebKit/NetworkProcess/NetworkProcessPlatformStrategies.cpp (280823 => 280824)
--- trunk/Source/WebKit/NetworkProcess/NetworkProcessPlatformStrategies.cpp 2021-08-10 03:11:48 UTC (rev 280823)
+++ trunk/Source/WebKit/NetworkProcess/NetworkProcessPlatformStrategies.cpp 2021-08-10 03:33:03 UTC (rev 280824)
@@ -65,6 +65,8 @@
void unregisterBlobURL(const URL&) final { ASSERT_NOT_REACHED(); }
unsigned long long blobSize(const URL&) final { ASSERT_NOT_REACHED(); return 0; }
void writeBlobsToTemporaryFiles(const Vector<String>& blobURLs, CompletionHandler<void(Vector<String>&& filePaths)>&&) final { ASSERT_NOT_REACHED(); }
+ void registerBlobURLHandle(const URL&) final { ASSERT_NOT_REACHED(); }
+ void unregisterBlobURLHandle(const URL&) final { ASSERT_NOT_REACHED(); }
};
static NeverDestroyed<EmptyBlobRegistry> blobRegistry;
return &blobRegistry.get();
Modified: trunk/Source/WebKit/WebProcess/FileAPI/BlobRegistryProxy.cpp (280823 => 280824)
--- trunk/Source/WebKit/WebProcess/FileAPI/BlobRegistryProxy.cpp 2021-08-10 03:11:48 UTC (rev 280823)
+++ trunk/Source/WebKit/WebProcess/FileAPI/BlobRegistryProxy.cpp 2021-08-10 03:33:03 UTC (rev 280824)
@@ -74,6 +74,16 @@
WebProcess::singleton().ensureNetworkProcessConnection().connection().send(Messages::NetworkConnectionToWebProcess::RegisterBlobURLForSlice(url, srcURL, start, end, contentType), 0);
}
+void BlobRegistryProxy::registerBlobURLHandle(const URL& url)
+{
+ WebProcess::singleton().ensureNetworkProcessConnection().connection().send(Messages::NetworkConnectionToWebProcess::RegisterBlobURLHandle(url), 0);
+}
+
+void BlobRegistryProxy::unregisterBlobURLHandle(const URL& url)
+{
+ WebProcess::singleton().ensureNetworkProcessConnection().connection().send(Messages::NetworkConnectionToWebProcess::UnregisterBlobURLHandle(url), 0);
+}
+
unsigned long long BlobRegistryProxy::blobSize(const URL& url)
{
uint64_t resultSize;
Modified: trunk/Source/WebKit/WebProcess/FileAPI/BlobRegistryProxy.h (280823 => 280824)
--- trunk/Source/WebKit/WebProcess/FileAPI/BlobRegistryProxy.h 2021-08-10 03:11:48 UTC (rev 280823)
+++ trunk/Source/WebKit/WebProcess/FileAPI/BlobRegistryProxy.h 2021-08-10 03:33:03 UTC (rev 280824)
@@ -39,6 +39,8 @@
void registerBlobURLForSlice(const URL&, const URL& srcURL, long long start, long long end, const String& contentType) final;
unsigned long long blobSize(const URL&) final;
void writeBlobsToTemporaryFiles(const Vector<String>& blobURLs, CompletionHandler<void(Vector<String>&& filePaths)>&&) final;
+ void registerBlobURLHandle(const URL&) final;
+ void unregisterBlobURLHandle(const URL&) final;
};
}
Modified: trunk/Source/WebKitLegacy/mac/ChangeLog (280823 => 280824)
--- trunk/Source/WebKitLegacy/mac/ChangeLog 2021-08-10 03:11:48 UTC (rev 280823)
+++ trunk/Source/WebKitLegacy/mac/ChangeLog 2021-08-10 03:33:03 UTC (rev 280824)
@@ -1,3 +1,12 @@
+2021-08-09 Chris Dumez <[email protected]>
+
+ Blob URL changes after loading it
+ https://bugs.webkit.org/show_bug.cgi?id=228923
+
+ Reviewed by Geoff Garen.
+
+ * WebCoreSupport/WebPlatformStrategies.mm:
+
2021-08-09 Myles C. Maxfield <[email protected]>
Support WTF logging channels
Modified: trunk/Source/WebKitLegacy/mac/WebCoreSupport/WebPlatformStrategies.mm (280823 => 280824)
--- trunk/Source/WebKitLegacy/mac/WebCoreSupport/WebPlatformStrategies.mm 2021-08-10 03:11:48 UTC (rev 280823)
+++ trunk/Source/WebKitLegacy/mac/WebCoreSupport/WebPlatformStrategies.mm 2021-08-10 03:33:03 UTC (rev 280824)
@@ -91,6 +91,8 @@
void unregisterBlobURL(const URL& url) final { m_blobRegistry.unregisterBlobURL(url); }
unsigned long long blobSize(const URL& url) final { return m_blobRegistry.blobSize(url); }
void writeBlobsToTemporaryFiles(const Vector<String>& blobURLs, CompletionHandler<void(Vector<String>&& filePaths)>&& completionHandler) final { m_blobRegistry.writeBlobsToTemporaryFiles(blobURLs, WTFMove(completionHandler)); }
+ void registerBlobURLHandle(const URL& url) final { m_blobRegistry.registerBlobURLHandle(url); }
+ void unregisterBlobURLHandle(const URL& url) final { m_blobRegistry.unregisterBlobURLHandle(url); }
BlobRegistryImpl* blobRegistryImpl() final { return &m_blobRegistry; }
Modified: trunk/Source/WebKitLegacy/win/ChangeLog (280823 => 280824)
--- trunk/Source/WebKitLegacy/win/ChangeLog 2021-08-10 03:11:48 UTC (rev 280823)
+++ trunk/Source/WebKitLegacy/win/ChangeLog 2021-08-10 03:33:03 UTC (rev 280824)
@@ -1,3 +1,12 @@
+2021-08-09 Chris Dumez <[email protected]>
+
+ Blob URL changes after loading it
+ https://bugs.webkit.org/show_bug.cgi?id=228923
+
+ Reviewed by Geoff Garen.
+
+ * WebCoreSupport/WebPlatformStrategies.cpp:
+
2021-08-09 Stephan Szabo <[email protected]>
[WinCairo][Debug] Build fix after r280756
Modified: trunk/Source/WebKitLegacy/win/WebCoreSupport/WebPlatformStrategies.cpp (280823 => 280824)
--- trunk/Source/WebKitLegacy/win/WebCoreSupport/WebPlatformStrategies.cpp 2021-08-10 03:11:48 UTC (rev 280823)
+++ trunk/Source/WebKitLegacy/win/WebCoreSupport/WebPlatformStrategies.cpp 2021-08-10 03:33:03 UTC (rev 280824)
@@ -87,6 +87,8 @@
void unregisterBlobURL(const URL& url) final { m_blobRegistry.unregisterBlobURL(url); }
unsigned long long blobSize(const URL& url) final { return m_blobRegistry.blobSize(url); }
void writeBlobsToTemporaryFiles(const Vector<String>& blobURLs, CompletionHandler<void(Vector<String>&& filePaths)>&& completionHandler) final { m_blobRegistry.writeBlobsToTemporaryFiles(blobURLs, WTFMove(completionHandler)); }
+ void registerBlobURLHandle(const URL& url) final { m_blobRegistry.registerBlobURLHandle(url); }
+ void unregisterBlobURLHandle(const URL& url) final { m_blobRegistry.unregisterBlobURLHandle(url); }
BlobRegistryImpl* blobRegistryImpl() final { return &m_blobRegistry; }