Reviewers: lazyboy,
Description:
<webview>: Navigate to about:blank if attempting to navigate to bad URL
If <webview> attempts to navigate to a URL that is invalid or it cannot
access, it will fire a loadabort message. However, a loadstop will not fire
and <webview> may remain in an unnavigated state despite having a set src
attribute. This causes various APIs such as executeScript to fail.
This CL navigates <webview> to about:blank in the case of a bad navigation.
This puts <webview> back to a sane state.
BUG=450125
Please review this at
https://codereview.chromium.org/888563003/
Base URL:
https://chromium.googlesource.com/chromium/src.git@master
Affected files (+43, -24 lines):
M chrome/test/data/extensions/platform_apps/web_view/shim/main.js
M extensions/browser/guest_view/web_view/web_view_guest.cc
M extensions/test/data/web_view/apitest/main.js
Index: chrome/test/data/extensions/platform_apps/web_view/shim/main.js
diff --git
a/chrome/test/data/extensions/platform_apps/web_view/shim/main.js
b/chrome/test/data/extensions/platform_apps/web_view/shim/main.js
index
91e7db85636620f7ad061c917fabad2c72d614f3..763b63d7155d859e0a699c501589697788150571
100644
--- a/chrome/test/data/extensions/platform_apps/web_view/shim/main.js
+++ b/chrome/test/data/extensions/platform_apps/web_view/shim/main.js
@@ -1421,16 +1421,14 @@ function testLoadAbortEmptyResponse() {
// chrome URL is provided.
function testLoadAbortIllegalChromeURL() {
var webview = document.createElement('webview');
- var onFirstLoadStop = function(e) {
- webview.removeEventListener('loadstop', onFirstLoadStop);
- webview.setAttribute('src', 'chrome://newtab');
- };
- webview.addEventListener('loadstop', onFirstLoadStop);
webview.addEventListener('loadabort', function(e) {
embedder.test.assertEq('ERR_ABORTED', e.reason);
+ });
+ webview.addEventListener('loadstop', function(e) {
+ embedder.test.assertEq('about:blank', webview.src);
embedder.test.succeed();
});
- webview.setAttribute('src', 'about:blank');
+ webview.src = 'chrome://newtab';
document.body.appendChild(webview);
}
@@ -1438,9 +1436,12 @@ function testLoadAbortIllegalFileURL() {
var webview = document.createElement('webview');
webview.addEventListener('loadabort', function(e) {
embedder.test.assertEq('ERR_ABORTED', e.reason);
+ });
+ webview.addEventListener('loadstop', function(e) {
+ embedder.test.assertEq('about:blank', webview.src);
embedder.test.succeed();
});
- webview.setAttribute('src', 'file://foo');
+ webview.src = 'file://foo';
document.body.appendChild(webview);
}
@@ -1448,6 +1449,9 @@ function testLoadAbortIllegalJavaScriptURL() {
var webview = document.createElement('webview');
webview.addEventListener('loadabort', function(e) {
embedder.test.assertEq('ERR_ABORTED', e.reason);
+ });
+ webview.addEventListener('loadstop', function(e) {
+ embedder.test.assertEq('about:blank', webview.src);
embedder.test.succeed();
});
webview.setAttribute('src', 'javascript:void(document.bgColor="#0000FF")');
@@ -1457,17 +1461,19 @@ function testLoadAbortIllegalJavaScriptURL() {
// Verifies that navigating to invalid URL (e.g. 'http:') doesn't cause a
crash.
function testLoadAbortInvalidNavigation() {
var webview = document.createElement('webview');
- var validSchemeWithEmptyURL = 'http:';
webview.addEventListener('loadabort', function(e) {
embedder.test.assertEq('ERR_ABORTED', e.reason);
embedder.test.assertEq('', e.url);
+ });
+ webview.addEventListener('loadstop', function(e) {
+ embedder.test.assertEq('about:blank', webview.src);
embedder.test.succeed();
});
webview.addEventListener('exit', function(e) {
// We should not crash.
embedder.test.fail();
});
- webview.setAttribute('src', validSchemeWithEmptyURL);
+ webview.src = 'http:';
document.body.appendChild(webview);
}
@@ -1475,17 +1481,20 @@ function testLoadAbortInvalidNavigation() {
// pseudo-scheme fires loadabort and doesn't cause a crash.
function testLoadAbortNonWebSafeScheme() {
var webview = document.createElement('webview');
- var chromeGuestURL = 'chrome-guest://abc123';
+ var chromeGuestURL = 'chrome-guest://abc123/';
webview.addEventListener('loadabort', function(e) {
embedder.test.assertEq('ERR_ABORTED', e.reason);
- embedder.test.assertEq('chrome-guest://abc123/', e.url);
+ embedder.test.assertEq(chromeGuestURL, e.url);
+ });
+ webview.addEventListener('loadstop', function(e) {
+ embedder.test.assertEq('about:blank', webview.src);
embedder.test.succeed();
});
webview.addEventListener('exit', function(e) {
// We should not crash.
embedder.test.fail();
});
- webview.setAttribute('src', chromeGuestURL);
+ webview.src = chromeGuestURL;
document.body.appendChild(webview);
};
Index: extensions/browser/guest_view/web_view/web_view_guest.cc
diff --git a/extensions/browser/guest_view/web_view/web_view_guest.cc
b/extensions/browser/guest_view/web_view/web_view_guest.cc
index
e9c25ba23e1afb1c42174ed948b7be2d1647e083..8eeb22da233cc69f49e63d1fb285fa9d4a680a8b
100644
--- a/extensions/browser/guest_view/web_view/web_view_guest.cc
+++ b/extensions/browser/guest_view/web_view/web_view_guest.cc
@@ -879,6 +879,7 @@ void WebViewGuest::NavigateGuest(const std::string& src,
if (scheme_is_blocked || !url.is_valid()) {
LoadAbort(true /* is_top_level */, url,
net::ErrorToShortString(net::ERR_ABORTED));
+ NavigateGuest("about:blank", true /* force_navigation */);
return;
}
if (!force_navigation && (src_ == url))
Index: extensions/test/data/web_view/apitest/main.js
diff --git a/extensions/test/data/web_view/apitest/main.js
b/extensions/test/data/web_view/apitest/main.js
index
4495ed432e3a273422948458b5a7092619c2fb68..95fee6e4de4fbb14ebbb88a0bcddf0a72a7bedff
100644
--- a/extensions/test/data/web_view/apitest/main.js
+++ b/extensions/test/data/web_view/apitest/main.js
@@ -964,16 +964,14 @@ function testLoadAbortEmptyResponse() {
// chrome URL is provided.
function testLoadAbortIllegalChromeURL() {
var webview = document.createElement('webview');
- var onFirstLoadStop = function(e) {
- webview.removeEventListener('loadstop', onFirstLoadStop);
- webview.setAttribute('src', 'chrome://newtab');
- };
- webview.addEventListener('loadstop', onFirstLoadStop);
webview.addEventListener('loadabort', function(e) {
embedder.test.assertEq('ERR_ABORTED', e.reason);
+ });
+ webview.addEventListener('loadstop', function(e) {
+ embedder.test.assertEq('about:blank', webview.src);
embedder.test.succeed();
});
- webview.setAttribute('src', 'about:blank');
+ webview.src = 'chrome://newtab';
document.body.appendChild(webview);
}
@@ -981,9 +979,12 @@ function testLoadAbortIllegalFileURL() {
var webview = document.createElement('webview');
webview.addEventListener('loadabort', function(e) {
embedder.test.assertEq('ERR_ABORTED', e.reason);
+ });
+ webview.addEventListener('loadstop', function(e) {
+ embedder.test.assertEq('about:blank', webview.src);
embedder.test.succeed();
});
- webview.setAttribute('src', 'file://foo');
+ webview.src = 'file://foo';
document.body.appendChild(webview);
}
@@ -991,6 +992,9 @@ function testLoadAbortIllegalJavaScriptURL() {
var webview = document.createElement('webview');
webview.addEventListener('loadabort', function(e) {
embedder.test.assertEq('ERR_ABORTED', e.reason);
+ });
+ webview.addEventListener('loadstop', function(e) {
+ embedder.test.assertEq('about:blank', webview.src);
embedder.test.succeed();
});
webview.setAttribute('src', 'javascript:void(document.bgColor="#0000FF")');
@@ -1000,17 +1004,19 @@ function testLoadAbortIllegalJavaScriptURL() {
// Verifies that navigating to invalid URL (e.g. 'http:') doesn't cause a
crash.
function testLoadAbortInvalidNavigation() {
var webview = document.createElement('webview');
- var validSchemeWithEmptyURL = 'http:';
webview.addEventListener('loadabort', function(e) {
embedder.test.assertEq('ERR_ABORTED', e.reason);
embedder.test.assertEq('', e.url);
+ });
+ webview.addEventListener('loadstop', function(e) {
+ embedder.test.assertEq('about:blank', webview.src);
embedder.test.succeed();
});
webview.addEventListener('exit', function(e) {
// We should not crash.
embedder.test.fail();
});
- webview.setAttribute('src', validSchemeWithEmptyURL);
+ webview.src = 'http:';
document.body.appendChild(webview);
}
@@ -1018,17 +1024,20 @@ function testLoadAbortInvalidNavigation() {
// pseudo-scheme fires loadabort and doesn't cause a crash.
function testLoadAbortNonWebSafeScheme() {
var webview = document.createElement('webview');
- var chromeGuestURL = 'chrome-guest://abc123';
+ var chromeGuestURL = 'chrome-guest://abc123/';
webview.addEventListener('loadabort', function(e) {
embedder.test.assertEq('ERR_ABORTED', e.reason);
- embedder.test.assertEq('chrome-guest://abc123/', e.url);
+ embedder.test.assertEq(chromeGuestURL, e.url);
+ });
+ webview.addEventListener('loadstop', function(e) {
+ embedder.test.assertEq('about:blank', webview.src);
embedder.test.succeed();
});
webview.addEventListener('exit', function(e) {
// We should not crash.
embedder.test.fail();
});
- webview.setAttribute('src', chromeGuestURL);
+ webview.src = chromeGuestURL;
document.body.appendChild(webview);
};