Bug 1228754, r=mak r=bz, a=sylvestre
MozReview-Commit-ID: IGGW2RGiN3u
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -2417,20 +2417,22 @@ function URLBarSetURI(aURI) {
let uri = aURI || gBrowser.currentURI;
// Strip off "wyciwyg://" and passwords for the location bar
try {
uri = Services.uriFixup.createExposableURI(uri);
} catch (e) {}
// Replace initial page URIs with an empty string
// only if there's no opener (bug 370555).
- if (gInitialPages.indexOf(uri.spec) != -1)
- value = gBrowser.selectedBrowser.hasContentOpener ? uri.spec : "";
- else
+ if (gInitialPages.indexOf(uri.spec) != -1 &&
+ checkEmptyPageOrigin(gBrowser.selectedBrowser, uri)) {
+ value = "";
+ } else {
value = losslessDecodeURI(uri);
+ }
valid = !isBlankPageURL(uri.spec);
}
gURLBar.value = value;
gURLBar.valueIsTyped = !valid;
SetPageProxyState(valid ? "valid" : "invalid");
}
@@ -4497,17 +4499,17 @@ var XULBrowserWindow = {
this.hideOverLinkImmediately = false;
// We should probably not do this if the value has changed since the user
// searched
// Update urlbar only if a new page was loaded on the primary content area
// Do not update urlbar if there was a subframe navigation
if (aWebProgress.isTopLevel) {
- if ((location == "about:blank" && !gBrowser.selectedBrowser.hasContentOpener) ||
+ if ((location == "about:blank" && checkEmptyPageOrigin()) ||
location == "") { // Second condition is for new tabs, otherwise
// reload function is enabled until tab is refreshed.
this.reloadCommand.setAttribute("disabled", "true");
} else {
this.reloadCommand.removeAttribute("disabled");
}
if (gURLBar) {
@@ -6604,25 +6606,76 @@ function undoCloseWindow(aIndex) {
function isTabEmpty(aTab) {
if (aTab.hasAttribute("busy"))
return false;
let browser = aTab.linkedBrowser;
if (!isBlankPageURL(browser.currentURI.spec))
return false;
- if (browser.hasContentOpener)
+ if (!checkEmptyPageOrigin(browser))
return false;
if (browser.canGoForward || browser.canGoBack)
return false;
return true;
}
+/**
+ * Check whether a page can be considered as 'empty', that its URI
+ * reflects its origin, and that if it's loaded in a tab, that tab
+ * could be considered 'empty' (e.g. like the result of opening
+ * a 'blank' new tab).
+ *
+ * We have to do more than just check the URI, because especially
+ * for things like about:blank, it is possible that the opener or
+ * some other page has control over the contents of the page.
+ *
+ * @param browser {Browser}
+ * The browser whose page we're checking (the selected browser
+ * in this window if omitted).
+ * @param uri {nsIURI}
+ * The URI against which we're checking (the browser's currentURI
+ * if omitted).
+ *
+ * @return false if the page was opened by or is controlled by arbitrary web
+ * content, unless that content corresponds with the URI.
+ * true if the page is blank and controlled by a principal matching
+ * that URI (or the system principal if the principal has no URI)
+ */
+function checkEmptyPageOrigin(browser = gBrowser.selectedBrowser,
+ uri = browser.currentURI) {
+ // If another page opened this page with e.g. window.open, this page might
+ // be controlled by its opener - return false.
+ if (browser.hasContentOpener) {
+ return false;
+ }
+ let contentPrincipal = browser.contentPrincipal;
+ if (gMultiProcessBrowser && browser.isRemoteBrowser &&
+ !contentPrincipal && uri.spec == "about:blank") {
+ // Need to specialcase this because of how stopping an about:blank
+ // load from chrome on e10s causes a permanently null contentPrincipal,
+ // see bug 1249362.
+ return true;
+ }
+ // Not all principals have URIs...
+ if (contentPrincipal.URI) {
+ // A manually entered about:blank URI is slightly magical:
+ if (uri.spec == "about:blank" && contentPrincipal.isNullPrincipal) {
+ return true;
+ }
+ return contentPrincipal.URI.equals(uri);
+ }
+ // ... so for those that don't have them, enforce that the page has the
+ // system principal (this matches e.g. on about:newtab).
+ let ssm = Services.scriptSecurityManager;
+ return ssm.isSystemPrincipal(contentPrincipal);
+}
+
function BrowserOpenSyncTabs() {
if (Services.prefs.getBoolPref("services.sync.syncedTabsUIRefresh")) {
gSyncUI.openSyncedTabsPanel();
} else {
switchToTabHavingURI("about:sync-tabs", true);
}
}
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/urlbar/browser.ini
@@ -0,0 +1,3 @@
+[browser_urlbar_blanking.js]
+support-files =
+ file_blank_but_not_blank.html
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/urlbar/browser_urlbar_blanking.js
@@ -0,0 +1,35 @@
+"use strict";
+
+add_task(function*() {
+ for (let page of gInitialPages) {
+ if (page == "about:newtab") {
+ // New tab preloading makes this a pain to test, so skip
+ continue;
+ }
+ let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, page);
+ ok(!gURLBar.value, "The URL bar should be empty if we load a plain " + page + " page.");
+ yield BrowserTestUtils.removeTab(tab);
+ }
+});
+
+add_task(function*() {
+ const URI = "http://www.example.com/browser/browser/base/content/test/urlbar/file_blank_but_not_blank.html";
+ let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, URI);
+ is(gURLBar.value, URI, "The URL bar should match the URI");
+ let browserLoaded = BrowserTestUtils.browserLoaded(tab.linkedBrowser);
+ ContentTask.spawn(tab.linkedBrowser, null, function() {
+ content.document.querySelector('a').click();
+ });
+ yield browserLoaded;
+ ok(gURLBar.value.startsWith("javascript"), "The URL bar should have the JS URI");
+ // When reloading, the javascript: uri we're using will throw an exception.
+ // That's deliberate, so we need to tell mochitest to ignore it:
+ SimpleTest.expectUncaughtException(true);
+ yield ContentTask.spawn(tab.linkedBrowser, null, function*() {
+ // This is sync, so by the time we return we should have changed the URL bar.
+ content.location.reload();
+ });
+ ok(!!gURLBar.value, "URL bar should not be blank.");
+ yield BrowserTestUtils.removeTab(tab);
+ SimpleTest.expectUncaughtException(false);
+});
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/urlbar/file_blank_but_not_blank.html
@@ -0,0 +1,2 @@
+<script>var q = 1;</script>
+<a href="javascript:q">Click me</a>
--- a/browser/base/moz.build
+++ b/browser/base/moz.build
@@ -18,16 +18,17 @@ BROWSER_CHROME_MANIFESTS += [
'content/test/alerts/browser.ini',
'content/test/chat/browser.ini',
'content/test/general/browser.ini',
'content/test/newtab/browser.ini',
'content/test/plugins/browser.ini',
'content/test/popupNotifications/browser.ini',
'content/test/referrer/browser.ini',
'content/test/social/browser.ini',
+ 'content/test/urlbar/browser.ini',
]
DEFINES['MOZ_APP_VERSION'] = CONFIG['MOZ_APP_VERSION']
DEFINES['MOZ_APP_VERSION_DISPLAY'] = CONFIG['MOZ_APP_VERSION_DISPLAY']
DEFINES['APP_LICENSE_BLOCK'] = '%s/content/overrides/app-license.html' % SRCDIR
if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('windows', 'gtk2', 'gtk3', 'cocoa'):