Commit 08784a11 authored by Marijn Kruisselbrink's avatar Marijn Kruisselbrink Committed by Commit Bot

[Mojo Blob URLs] Make clicking an <a target="blank_"> with a blob URL work correctly.

This goes through a code-path where the blob URL token was incorrectly
dropped, so make sure we copy the token from the old FrameLoadRequest to
the new FrameLoadRequest.

Adds a web-platform-test to verify this behavior, and enables the blob URL browser
tests to also run with MojoBlobURLs enabled. This browser test required another
bug fix in RenderFrameHostImpl.

Cq-Include-Trybots: luci.chromium.try:linux_mojo
Bug: 800901
Change-Id: I87eee70e784dd8cb273f8671f37b00d8a93d9543
Reviewed-on: https://chromium-review.googlesource.com/1102820Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Reviewed-by: default avatarDmitry Gozman <dgozman@chromium.org>
Commit-Queue: Marijn Kruisselbrink <mek@chromium.org>
Cr-Commit-Position: refs/heads/master@{#568071}
parent ac6758ac
......@@ -6,6 +6,7 @@
#include "base/strings/pattern.h"
#include "build/build_config.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/common/content_switches.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_utils.h"
......@@ -20,7 +21,8 @@
namespace content {
// Tests of the blob: URL scheme.
class BlobUrlBrowserTest : public ContentBrowserTest {
class BlobUrlBrowserTest : public ContentBrowserTest,
public testing::WithParamInterface<bool> {
public:
BlobUrlBrowserTest() {}
......@@ -30,11 +32,20 @@ class BlobUrlBrowserTest : public ContentBrowserTest {
ASSERT_TRUE(embedded_test_server()->Start());
}
void SetUpCommandLine(base::CommandLine* command_line) override {
if (GetParam()) {
command_line->AppendSwitchASCII(switches::kEnableBlinkFeatures,
"MojoBlobURLs");
}
}
private:
DISALLOW_COPY_AND_ASSIGN(BlobUrlBrowserTest);
};
IN_PROC_BROWSER_TEST_F(BlobUrlBrowserTest, LinkToUniqueOriginBlob) {
INSTANTIATE_TEST_CASE_P(_, BlobUrlBrowserTest, ::testing::Bool());
IN_PROC_BROWSER_TEST_P(BlobUrlBrowserTest, LinkToUniqueOriginBlob) {
// Use a data URL to obtain a test page in a unique origin. The page
// contains a link to a "blob:null/SOME-GUID-STRING" URL.
NavigateToURL(
......@@ -68,7 +79,7 @@ IN_PROC_BROWSER_TEST_F(BlobUrlBrowserTest, LinkToUniqueOriginBlob) {
EXPECT_EQ("null potato", page_content);
}
IN_PROC_BROWSER_TEST_F(BlobUrlBrowserTest, LinkToSameOriginBlob) {
IN_PROC_BROWSER_TEST_P(BlobUrlBrowserTest, LinkToSameOriginBlob) {
// Using an http page, click a link that opens a popup to a same-origin blob.
GURL url = embedded_test_server()->GetURL("chromium.org", "/title1.html");
url::Origin origin = url::Origin::Create(url);
......@@ -100,7 +111,7 @@ IN_PROC_BROWSER_TEST_F(BlobUrlBrowserTest, LinkToSameOriginBlob) {
}
// Regression test for https://crbug.com/646278
IN_PROC_BROWSER_TEST_F(BlobUrlBrowserTest, LinkToSameOriginBlobWithAuthority) {
IN_PROC_BROWSER_TEST_P(BlobUrlBrowserTest, LinkToSameOriginBlobWithAuthority) {
// Using an http page, click a link that opens a popup to a same-origin blob
// that has a spoofy authority section applied. This should be blocked.
GURL url = embedded_test_server()->GetURL("chromium.org", "/title1.html");
......@@ -138,7 +149,7 @@ IN_PROC_BROWSER_TEST_F(BlobUrlBrowserTest, LinkToSameOriginBlobWithAuthority) {
}
// Regression test for https://crbug.com/646278
IN_PROC_BROWSER_TEST_F(BlobUrlBrowserTest, ReplaceStateToAddAuthorityToBlob) {
IN_PROC_BROWSER_TEST_P(BlobUrlBrowserTest, ReplaceStateToAddAuthorityToBlob) {
// history.replaceState from a validly loaded blob URL shouldn't allow adding
// an authority to the inner URL, which would be spoofy.
GURL url = embedded_test_server()->GetURL("chromium.org", "/title1.html");
......
......@@ -3159,6 +3159,12 @@ void RenderFrameHostImpl::BeginNavigation(
return;
}
// If the request was for a blob URL, but the validated URL is no longer a
// blob URL, reset the blob_url_token to prevent hitting the ReportBadMessage
// below, and to make sure we don't incorrectly try to use the blob_url_token.
if (common_params.url.SchemeIsBlob() && !validated_params.url.SchemeIsBlob())
blob_url_token = nullptr;
if (blob_url_token && !validated_params.url.SchemeIsBlob()) {
mojo::ReportBadMessage("Blob URL Token, but not a blob: URL");
return;
......
......@@ -97,3 +97,18 @@ async_test(t => {
document.body.appendChild(e);
URL.revokeObjectURL(url);
}, 'Fetching a blob URL immediately before revoking it works in <script> tags.');
async_test(t => {
const channel_name = 'a-click-test';
const blob = new Blob([window_contents_for_channel(channel_name)], {type: 'text/html'});
receive_message_on_channel(t, channel_name).then(t.step_func_done(t => {
assert_equals(t, 'foobar');
}));
const url = URL.createObjectURL(blob);
const anchor = document.createElement('a');
anchor.href = url;
anchor.target = '_blank';
document.body.appendChild(anchor);
anchor.click();
URL.revokeObjectURL(url);
}, 'Opening a blob URL in a new window by clicking an <a> tag works immediately before revoking the URL.');
......@@ -442,6 +442,9 @@ void CreateWindowForRequest(const FrameLoadRequest& request,
// TODO(japhet): Form submissions on RemoteFrames don't work yet.
FrameLoadRequest new_request(nullptr, request.GetResourceRequest());
new_request.SetForm(request.Form());
auto blob_url_token = request.GetBlobURLToken();
if (blob_url_token)
new_request.SetBlobURLToken(std::move(blob_url_token));
if (new_frame->IsLocalFrame())
ToLocalFrame(new_frame)->Loader().StartNavigation(new_request);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment