WebKit Bugzilla
Attachment 340199 Details for
Bug 185531
: REGRESSION (async policy delegate): Revoking an object URL immediately after triggering download breaks file download
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-185531-20180511104119.patch (text/plain), 22.05 KB, created by
Chris Dumez
on 2018-05-11 10:41:20 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Chris Dumez
Created:
2018-05-11 10:41:20 PDT
Size:
22.05 KB
patch
obsolete
>Subversion Revision: 231654 >diff --git a/Source/WTF/ChangeLog b/Source/WTF/ChangeLog >index 571658db3822b8b099d20b4c98e4ca34a8aba4b7..43dde7d04dbd952e9668786ebc5b4b78d310cb65 100644 >--- a/Source/WTF/ChangeLog >+++ b/Source/WTF/ChangeLog >@@ -1,3 +1,15 @@ >+2018-05-11 Chris Dumez <cdumez@apple.com> >+ >+ REGRESSION (async policy delegate): Revoking an object URL immediately after triggering download breaks file download >+ https://bugs.webkit.org/show_bug.cgi?id=185531 >+ <rdar://problem/39909589> >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Add a default constructor for CompletionHandlerCallingScope, for convenience. >+ >+ * wtf/CompletionHandler.h: >+ > 2018-05-10 Tim Horton <timothy_horton@apple.com> > > Fix the build after r231393 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index 8c7ef67f825183403d835e517da46ea83a49b4d0..230796a195d3b48ea910b61ebaced07940fe9e53 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,29 @@ >+2018-05-11 Chris Dumez <cdumez@apple.com> >+ >+ REGRESSION (async policy delegate): Revoking an object URL immediately after triggering download breaks file download >+ https://bugs.webkit.org/show_bug.cgi?id=185531 >+ <rdar://problem/39909589> >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Whenever we start an asynchronous navigation policy decision for a blob URL, create a temporary >+ blob URL pointing to the same data, and update the request's URL. This way, if the page's JS revokes >+ the URL during the policy decision, the load will still succeed. >+ >+ Test: fast/dom/HTMLAnchorElement/anchor-file-blob-download-then-revoke.html >+ >+ * loader/DocumentLoader.cpp: >+ (WebCore::DocumentLoader::willSendRequest): >+ * loader/FrameLoader.cpp: >+ (WebCore::FrameLoader::loadURL): >+ (WebCore::FrameLoader::load): >+ (WebCore::FrameLoader::loadPostRequest): >+ * loader/PolicyChecker.cpp: >+ (WebCore::PolicyChecker::extendBlobURLLifetimeIfNecessary const): >+ (WebCore::PolicyChecker::checkNavigationPolicy): >+ (WebCore::PolicyChecker::checkNewWindowPolicy): >+ * loader/PolicyChecker.h: >+ > 2018-05-10 Chris Dumez <cdumez@apple.com> > > 'Cross-Origin-Options header implementation follow-up >diff --git a/Source/WTF/wtf/CompletionHandler.h b/Source/WTF/wtf/CompletionHandler.h >index e02faf1bec79323d59e988af0d50a163b0d148af..7a25a5e3442ebefb4721b4d7ca2650e9b8b0972f 100644 >--- a/Source/WTF/wtf/CompletionHandler.h >+++ b/Source/WTF/wtf/CompletionHandler.h >@@ -66,6 +66,8 @@ private: > > class CompletionHandlerCallingScope { > public: >+ CompletionHandlerCallingScope() = default; >+ > CompletionHandlerCallingScope(CompletionHandler<void()>&& completionHandler) > : m_completionHandler(WTFMove(completionHandler)) > { } >diff --git a/Source/WebCore/loader/DocumentLoader.cpp b/Source/WebCore/loader/DocumentLoader.cpp >index 2e2b7638136722868421815b92c74e30c18af870..df8c58c114cc2bfd00824581d5c8916a01365ca8 100644 >--- a/Source/WebCore/loader/DocumentLoader.cpp >+++ b/Source/WebCore/loader/DocumentLoader.cpp >@@ -664,7 +664,7 @@ void DocumentLoader::willSendRequest(ResourceRequest&& newRequest, const Resourc > return; > } > >- frameLoader()->policyChecker().checkNavigationPolicy(ResourceRequest(newRequest), didReceiveRedirectResponse, WTFMove(navigationPolicyCompletionHandler)); >+ frameLoader()->policyChecker().checkNavigationPolicy(WTFMove(newRequest), didReceiveRedirectResponse, WTFMove(navigationPolicyCompletionHandler)); > } > > bool DocumentLoader::tryLoadingRequestFromApplicationCache() >diff --git a/Source/WebCore/loader/FrameLoader.cpp b/Source/WebCore/loader/FrameLoader.cpp >index 1b7a099307317386aeb57219a74d76a0156988d4..affd07d1fdf6fca4b70e835a871ffa6319e27312 100644 >--- a/Source/WebCore/loader/FrameLoader.cpp >+++ b/Source/WebCore/loader/FrameLoader.cpp >@@ -1336,7 +1336,7 @@ void FrameLoader::loadURL(FrameLoadRequest&& frameLoadRequest, const String& ref > > if (!targetFrame && !frameName.isEmpty()) { > action = action.copyWithShouldOpenExternalURLsPolicy(shouldOpenExternalURLsPolicyToApply(m_frame, frameLoadRequest)); >- policyChecker().checkNewWindowPolicy(WTFMove(action), request, formState, frameName, [this, allowNavigationToInvalidURL, openerPolicy, completionHandler = completionHandlerCaller.release()] (const ResourceRequest& request, FormState* formState, const String& frameName, const NavigationAction& action, ShouldContinue shouldContinue) { >+ policyChecker().checkNewWindowPolicy(WTFMove(action), WTFMove(request), formState, frameName, [this, allowNavigationToInvalidURL, openerPolicy, completionHandler = completionHandlerCaller.release()] (const ResourceRequest& request, FormState* formState, const String& frameName, const NavigationAction& action, ShouldContinue shouldContinue) { > continueLoadAfterNewWindowPolicy(request, formState, frameName, action, shouldContinue, allowNavigationToInvalidURL, openerPolicy); > completionHandler(); > }); >@@ -1356,7 +1356,7 @@ void FrameLoader::loadURL(FrameLoadRequest&& frameLoadRequest, const String& ref > oldDocumentLoader->setLastCheckedRequest(ResourceRequest()); > policyChecker().stopCheck(); > policyChecker().setLoadType(newLoadType); >- policyChecker().checkNavigationPolicy(ResourceRequest(request), false /* didReceiveRedirectResponse */, oldDocumentLoader.get(), formState, [this, protectedFrame = makeRef(m_frame)] (const ResourceRequest& request, FormState*, ShouldContinue shouldContinue) { >+ policyChecker().checkNavigationPolicy(WTFMove(request), false /* didReceiveRedirectResponse */, oldDocumentLoader.get(), formState, [this, protectedFrame = makeRef(m_frame)] (const ResourceRequest& request, FormState*, ShouldContinue shouldContinue) { > continueFragmentScrollAfterNavigationPolicy(request, shouldContinue == ShouldContinue::Yes); > }, PolicyDecisionMode::Synchronous); > return; >@@ -1412,7 +1412,7 @@ void FrameLoader::load(FrameLoadRequest&& request) > > if (request.shouldCheckNewWindowPolicy()) { > NavigationAction action { request.requester(), request.resourceRequest(), InitiatedByMainFrame::Unknown, NavigationType::Other, request.shouldOpenExternalURLsPolicy() }; >- policyChecker().checkNewWindowPolicy(WTFMove(action), request.resourceRequest(), nullptr, request.frameName(), [this] (const ResourceRequest& request, FormState* formState, const String& frameName, const NavigationAction& action, ShouldContinue shouldContinue) { >+ policyChecker().checkNewWindowPolicy(WTFMove(action), WTFMove(request.resourceRequest()), nullptr, request.frameName(), [this] (const ResourceRequest& request, FormState* formState, const String& frameName, const NavigationAction& action, ShouldContinue shouldContinue) { > continueLoadAfterNewWindowPolicy(request, formState, frameName, action, shouldContinue, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Suppress); > }); > >@@ -2858,7 +2858,7 @@ void FrameLoader::loadPostRequest(FrameLoadRequest&& request, const String& refe > return; > } > >- policyChecker().checkNewWindowPolicy(WTFMove(action), workingResourceRequest, WTFMove(formState), frameName, [this, allowNavigationToInvalidURL, openerPolicy, completionHandler = WTFMove(completionHandler)] (const ResourceRequest& request, FormState* formState, const String& frameName, const NavigationAction& action, ShouldContinue shouldContinue) { >+ policyChecker().checkNewWindowPolicy(WTFMove(action), WTFMove(workingResourceRequest), WTFMove(formState), frameName, [this, allowNavigationToInvalidURL, openerPolicy, completionHandler = WTFMove(completionHandler)] (const ResourceRequest& request, FormState* formState, const String& frameName, const NavigationAction& action, ShouldContinue shouldContinue) { > continueLoadAfterNewWindowPolicy(request, formState, frameName, action, shouldContinue, allowNavigationToInvalidURL, openerPolicy); > completionHandler(); > }); >diff --git a/Source/WebCore/loader/PolicyChecker.cpp b/Source/WebCore/loader/PolicyChecker.cpp >index fc2419498384d22bdf6d7a7d926ec53c6b04ad58..53d19a4d1a603a2ab9333676bf0134e71966ec90 100644 >--- a/Source/WebCore/loader/PolicyChecker.cpp >+++ b/Source/WebCore/loader/PolicyChecker.cpp >@@ -31,6 +31,8 @@ > #include "config.h" > #include "PolicyChecker.h" > >+#include "BlobRegistry.h" >+#include "BlobURL.h" > #include "ContentFilter.h" > #include "ContentSecurityPolicy.h" > #include "DOMWindow.h" >@@ -81,6 +83,20 @@ void PolicyChecker::checkNavigationPolicy(ResourceRequest&& newRequest, bool did > checkNavigationPolicy(WTFMove(newRequest), didReceiveRedirectResponse, m_frame.loader().activeDocumentLoader(), nullptr, WTFMove(function)); > } > >+CompletionHandlerCallingScope PolicyChecker::extendBlobURLLifetimeIfNecessary(ResourceRequest& request) const >+{ >+ if (!request.url().protocolIsBlob()) >+ return { }; >+ >+ // Create a new temporary blobURL in case this one gets revoked during the asynchronous navigation policy decision. >+ URL temporaryBlobURL = BlobURL::createPublicURL(&m_frame.document()->securityOrigin()); >+ blobRegistry().registerBlobURL(temporaryBlobURL, request.url()); >+ request.setURL(temporaryBlobURL); >+ return CompletionHandler<void()>([temporaryBlobURL = WTFMove(temporaryBlobURL)] { >+ blobRegistry().unregisterBlobURL(temporaryBlobURL); >+ }); >+} >+ > void PolicyChecker::checkNavigationPolicy(ResourceRequest&& request, bool didReceiveRedirectResponse, DocumentLoader* loader, FormState* formState, NavigationPolicyDecisionFunction&& function, PolicyDecisionMode policyDecisionMode) > { > NavigationAction action = loader->triggeringAction(); >@@ -147,10 +163,11 @@ void PolicyChecker::checkNavigationPolicy(ResourceRequest&& request, bool didRec > > m_frame.loader().clearProvisionalLoadForPolicyCheck(); > >+ auto blobURLLifetimeExtension = policyDecisionMode == PolicyDecisionMode::Asynchronous ? extendBlobURLLifetimeIfNecessary(request) : CompletionHandlerCallingScope { }; >+ > m_delegateIsDecidingNavigationPolicy = true; > String suggestedFilename = action.downloadAttribute().isEmpty() ? nullAtom() : action.downloadAttribute(); >- ResourceRequest requestCopy = request; >- m_frame.loader().client().dispatchDecidePolicyForNavigationAction(action, request, didReceiveRedirectResponse, formState, policyDecisionMode, [this, function = WTFMove(function), request = WTFMove(requestCopy), formState = makeRefPtr(formState), suggestedFilename = WTFMove(suggestedFilename)](PolicyAction policyAction) mutable { >+ m_frame.loader().client().dispatchDecidePolicyForNavigationAction(action, request, didReceiveRedirectResponse, formState, policyDecisionMode, [this, function = WTFMove(function), request = ResourceRequest(request), formState = makeRefPtr(formState), suggestedFilename = WTFMove(suggestedFilename), blobURLLifetimeExtension = WTFMove(blobURLLifetimeExtension)](PolicyAction policyAction) mutable { > m_delegateIsDecidingNavigationPolicy = false; > > switch (policyAction) { >@@ -173,7 +190,7 @@ void PolicyChecker::checkNavigationPolicy(ResourceRequest&& request, bool didRec > }); > } > >-void PolicyChecker::checkNewWindowPolicy(NavigationAction&& navigationAction, const ResourceRequest& request, FormState* formState, const String& frameName, NewWindowPolicyDecisionFunction&& function) >+void PolicyChecker::checkNewWindowPolicy(NavigationAction&& navigationAction, ResourceRequest&& request, FormState* formState, const String& frameName, NewWindowPolicyDecisionFunction&& function) > { > if (m_frame.document() && m_frame.document()->isSandboxed(SandboxPopups)) > return function({ }, nullptr, { }, { }, ShouldContinue::No); >@@ -181,7 +198,9 @@ void PolicyChecker::checkNewWindowPolicy(NavigationAction&& navigationAction, co > if (!DOMWindow::allowPopUp(m_frame)) > return function({ }, nullptr, { }, { }, ShouldContinue::No); > >- m_frame.loader().client().dispatchDecidePolicyForNewWindowAction(navigationAction, request, formState, frameName, [frame = makeRef(m_frame), request, formState = makeRefPtr(formState), frameName, navigationAction, function = WTFMove(function)](PolicyAction policyAction) mutable { >+ auto blobURLLifetimeExtension = extendBlobURLLifetimeIfNecessary(request); >+ >+ m_frame.loader().client().dispatchDecidePolicyForNewWindowAction(navigationAction, request, formState, frameName, [frame = makeRef(m_frame), request, formState = makeRefPtr(formState), frameName, navigationAction, function = WTFMove(function), blobURLLifetimeExtension = WTFMove(blobURLLifetimeExtension)](PolicyAction policyAction) mutable { > switch (policyAction) { > case PolicyAction::Download: > frame->loader().client().startDownload(request); >diff --git a/Source/WebCore/loader/PolicyChecker.h b/Source/WebCore/loader/PolicyChecker.h >index b16c1ee2594dd7db157e43ee4d8396f6d75a7381..c329ec43b81e35e8b73abe6e601d13d4250852af 100644 >--- a/Source/WebCore/loader/PolicyChecker.h >+++ b/Source/WebCore/loader/PolicyChecker.h >@@ -39,6 +39,7 @@ > > namespace WTF { > template<typename> class CompletionHandler; >+class CompletionHandlerCallingScope; > } > > namespace WebCore { >@@ -69,7 +70,7 @@ public: > > void checkNavigationPolicy(ResourceRequest&&, bool didReceiveRedirectResponse, DocumentLoader*, FormState*, NavigationPolicyDecisionFunction&&, PolicyDecisionMode = PolicyDecisionMode::Asynchronous); > void checkNavigationPolicy(ResourceRequest&&, bool didReceiveRedirectResponse, NavigationPolicyDecisionFunction&&); >- void checkNewWindowPolicy(NavigationAction&&, const ResourceRequest&, FormState*, const String& frameName, NewWindowPolicyDecisionFunction&&); >+ void checkNewWindowPolicy(NavigationAction&&, ResourceRequest&&, FormState*, const String& frameName, NewWindowPolicyDecisionFunction&&); > > void stopCheck(); > >@@ -87,6 +88,7 @@ public: > > private: > void handleUnimplementablePolicy(const ResourceError&); >+ WTF::CompletionHandlerCallingScope extendBlobURLLifetimeIfNecessary(ResourceRequest&) const; > > Frame& m_frame; > >diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog >index dd871f09cc6f5c49066135edcd7fdf9a65ee7eaa..2c5de6f102b8565e5b4512d04f23300f88daad30 100644 >--- a/LayoutTests/ChangeLog >+++ b/LayoutTests/ChangeLog >@@ -1,3 +1,22 @@ >+2018-05-11 Chris Dumez <cdumez@apple.com> >+ >+ REGRESSION (async policy delegate): Revoking an object URL immediately after triggering download breaks file download >+ https://bugs.webkit.org/show_bug.cgi?id=185531 >+ <rdar://problem/39909589> >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * fast/dom/HTMLAnchorElement/anchor-file-blob-download-then-revoke-expected.txt: Added. >+ * fast/dom/HTMLAnchorElement/anchor-file-blob-download-then-revoke.html: Added. >+ Add layout test coverage. >+ >+ * platform/ios-wk1/TestExpectations: >+ * platform/ios-wk2/TestExpectations: >+ * platform/mac-wk1/TestExpectations: >+ * platform/win/TestExpectations: >+ * platform/wincairo/TestExpectations: >+ Skip new test on platforms that do not support the download attribute. >+ > 2018-05-10 Chris Dumez <cdumez@apple.com> > > 'Cross-Origin-Options header implementation follow-up >diff --git a/LayoutTests/fast/dom/HTMLAnchorElement/anchor-file-blob-download-then-revoke-expected.txt b/LayoutTests/fast/dom/HTMLAnchorElement/anchor-file-blob-download-then-revoke-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..d2b6224077a4f5ef1b6b69632c4bc245e9aef742 >--- /dev/null >+++ b/LayoutTests/fast/dom/HTMLAnchorElement/anchor-file-blob-download-then-revoke-expected.txt >@@ -0,0 +1,7 @@ >+CONSOLE MESSAGE: line 37: PASS: URL was revoked >+Download started. >+Downloading URL with suggested filename "foo.txt" >+Download completed. >+The suggested filename above should be "foo.txt" and the download should succeed. >+ >+Memory backed blob URL >diff --git a/LayoutTests/fast/dom/HTMLAnchorElement/anchor-file-blob-download-then-revoke.html b/LayoutTests/fast/dom/HTMLAnchorElement/anchor-file-blob-download-then-revoke.html >new file mode 100644 >index 0000000000000000000000000000000000000000..70723c4b16e3e2eb2998e19421654e20abf87b57 >--- /dev/null >+++ b/LayoutTests/fast/dom/HTMLAnchorElement/anchor-file-blob-download-then-revoke.html >@@ -0,0 +1,42 @@ >+<!DOCTYPE html> >+<html> >+<head> >+<script> >+if (window.testRunner) { >+ testRunner.dumpAsText(); >+ testRunner.setShouldLogDownloadCallbacks(true); >+ testRunner.waitUntilDownloadFinished(); >+} >+</script> >+</head> >+<body> >+<p>The suggested filename above should be "foo.txt" and the download should succeed.</p> >+<a id="blob-url" download="foo">Memory backed blob URL</a> >+<script> >+function runTest() >+{ >+ file = new File(["foo"], "foo.txt", { >+ type: "text/plain" >+ }); >+ var link = document.getElementById("blob-url"); >+ link.href = window.URL.createObjectURL(file); >+ 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> >+</body> >+</html> >diff --git a/LayoutTests/platform/ios-wk1/TestExpectations b/LayoutTests/platform/ios-wk1/TestExpectations >index 0b4a3ca75dfaf633dfe69ce6900ff3221244d253..99b52816de00c43fd2960c8b3c3d8d07a3eb9e1b 100644 >--- a/LayoutTests/platform/ios-wk1/TestExpectations >+++ b/LayoutTests/platform/ios-wk1/TestExpectations >@@ -1366,6 +1366,7 @@ webkit.org/b/156069 fast/dom/HTMLAnchorElement/anchor-file-blob-download-include > webkit.org/b/156069 fast/dom/HTMLAnchorElement/anchor-file-blob-download-includes-doublequote.html [ Skip ] > webkit.org/b/156069 fast/dom/HTMLAnchorElement/anchor-file-blob-download-includes-slashes.html [ Skip ] > webkit.org/b/156069 fast/dom/HTMLAnchorElement/anchor-file-blob-download-includes-unicode.html [ Skip ] >+webkit.org/b/156069 fast/dom/HTMLAnchorElement/anchor-file-blob-download-then-revoke.html [ Skip ] > webkit.org/b/156069 http/tests/download/area-download.html [ Skip ] > webkit.org/b/156069 http/tests/security/anchor-download-allow-blob.html [ Skip ] > webkit.org/b/156069 http/tests/security/anchor-download-allow-data.html [ Skip ] >diff --git a/LayoutTests/platform/ios-wk2/TestExpectations b/LayoutTests/platform/ios-wk2/TestExpectations >index c1e5d44ada5af6ec0d48950a717c8ad8e4a1bb4c..80e2bc06469ad41e5eabfdb9efd7d62de35e6237 100644 >--- a/LayoutTests/platform/ios-wk2/TestExpectations >+++ b/LayoutTests/platform/ios-wk2/TestExpectations >@@ -1156,6 +1156,7 @@ webkit.org/b/156067 fast/dom/HTMLAnchorElement/anchor-file-blob-download-include > webkit.org/b/156067 fast/dom/HTMLAnchorElement/anchor-file-blob-download-includes-slashes.html [ Skip ] > webkit.org/b/156067 fast/dom/HTMLAnchorElement/anchor-file-blob-download-includes-unicode.html [ Skip ] > webkit.org/b/156067 fast/dom/HTMLAnchorElement/anchor-file-blob-download-no-extension.html [ Skip ] >+webkit.org/b/156067 fast/dom/HTMLAnchorElement/anchor-file-blob-download-then-revoke.html [ Skip ] > webkit.org/b/156067 fast/dom/HTMLAnchorElement/anchor-nodownload-set.html [ Skip ] > webkit.org/b/156067 fast/dom/HTMLAnchorElement/anchor-nodownload.html [ Skip ] > webkit.org/b/156067 fast/dom/HTMLAnchorElement/anchor-download-synthetic-click.html [ Skip ] >diff --git a/LayoutTests/platform/mac-wk1/TestExpectations b/LayoutTests/platform/mac-wk1/TestExpectations >index df0f144c9b130c01a16dd411d159c014aff942a1..784767028938b12f05c3773d96d96a70bf776fee 100644 >--- a/LayoutTests/platform/mac-wk1/TestExpectations >+++ b/LayoutTests/platform/mac-wk1/TestExpectations >@@ -300,6 +300,7 @@ webkit.org/b/156069 fast/dom/HTMLAnchorElement/anchor-file-blob-download-include > webkit.org/b/156069 fast/dom/HTMLAnchorElement/anchor-file-blob-download-includes-slashes.html [ Skip ] > webkit.org/b/156069 fast/dom/HTMLAnchorElement/anchor-file-blob-download-includes-unicode.html [ Skip ] > webkit.org/b/156069 fast/dom/HTMLAnchorElement/anchor-file-blob-download-no-extension.html [ Skip ] >+webkit.org/b/156069 fast/dom/HTMLAnchorElement/anchor-file-blob-download-then-revoke.html [ Skip ] > webkit.org/b/156069 http/tests/download/anchor-download-attribute-content-disposition.html [ Skip ] > webkit.org/b/156069 http/tests/download/anchor-download-no-extension.html [ Skip ] > webkit.org/b/156069 http/tests/download/anchor-download-redirect.html [ Skip ] >diff --git a/LayoutTests/platform/win/TestExpectations b/LayoutTests/platform/win/TestExpectations >index d83d77df329d385416223a7ce21248cad6492abd..3c11c03621298b0597f720d2bea16038834cce32 100644 >--- a/LayoutTests/platform/win/TestExpectations >+++ b/LayoutTests/platform/win/TestExpectations >@@ -446,6 +446,7 @@ fast/dom/HTMLAnchorElement/anchor-file-blob-download-includes-doublequote.html [ > fast/dom/HTMLAnchorElement/anchor-file-blob-download-includes-slashes.html [ Skip ] > fast/dom/HTMLAnchorElement/anchor-file-blob-download-includes-unicode.html [ Skip ] > fast/dom/HTMLAnchorElement/anchor-file-blob-download-no-extension.html [ Skip ] >+fast/dom/HTMLAnchorElement/anchor-file-blob-download-then-revoke.html [ Skip ] > http/tests/download/anchor-download-attribute-content-disposition.html [ Skip ] > http/tests/download/anchor-download-no-extension.html [ Skip ] > http/tests/download/area-download.html [ Skip ] >diff --git a/LayoutTests/platform/wincairo/TestExpectations b/LayoutTests/platform/wincairo/TestExpectations >index dfbb498a48d095f58c68bd2b38cda7dffc1947c1..93b69bb7a85530e6a55eb97f37fddfdd34e91d42 100644 >--- a/LayoutTests/platform/wincairo/TestExpectations >+++ b/LayoutTests/platform/wincairo/TestExpectations >@@ -66,6 +66,7 @@ fast/dom/HTMLAnchorElement/anchor-file-blob-download-includes-doublequote.html [ > fast/dom/HTMLAnchorElement/anchor-file-blob-download-includes-slashes.html [ Skip ] > fast/dom/HTMLAnchorElement/anchor-file-blob-download-includes-unicode.html [ Skip ] > fast/dom/HTMLAnchorElement/anchor-file-blob-download-no-extension.html [ Skip ] >+fast/dom/HTMLAnchorElement/anchor-file-blob-download-then-revoke.html [ Skip ] > fast/dom/HTMLAnchorElement/anchor-nodownload-set.html [ Skip ] > > # ENABLE_INPUT_TYPE_* are disabled.
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 185531
:
340141
|
340148
|
340150
|
340156
| 340199