Bug 1199934 - page shouldn't be able to trap/revert the location bar by hash/replacestate changes, r?jaws
MozReview-Commit-ID: HsmmHsUtU0h
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -753,21 +753,21 @@
!!(aFlags & Ci.nsIWebProgressListener.LOCATION_CHANGE_SAME_DOCUMENT);
// If userTypedClear > 0, the document loaded correctly and we should be
// clearing the user typed value. We also need to clear the typed value
// if the document failed to load, to make sure the urlbar reflects the
// failed URI (particularly for SSL errors). However, don't clear the value
// if the error page's URI is about:blank, because that causes complete
// loss of urlbar contents for invalid URI errors (see bug 867957).
// Another reason to clear the userTypedValue is if this was an anchor
- // navigation.
+ // navigation initiated by the user.
if (this.mBrowser.userTypedClear > 0 ||
((aFlags & Ci.nsIWebProgressListener.LOCATION_CHANGE_ERROR_PAGE) &&
aLocation.spec != "about:blank") ||
- isSameDocument) {
+ (isSameDocument && this.mBrowser.inLoadURI)) {
this.mBrowser.userTypedValue = null;
}
// If the browser was playing audio, we should remove the playing state.
if (this.mTab.hasAttribute("soundplaying") && !isSameDocument) {
this.mTab.removeAttribute("soundplaying");
this.mTabBrowser._tabAttrModified(this.mTab, ["soundplaying"]);
}
--- a/browser/base/content/test/urlbar/browser.ini
+++ b/browser/base/content/test/urlbar/browser.ini
@@ -1,7 +1,10 @@
[browser_moz_action_link.js]
[browser_urlbar_blanking.js]
support-files =
file_blank_but_not_blank.html
+[browser_urlbar_locationchange_urlbar_edit_dos.js]
+support-files =
+ file_urlbar_edit_dos.html
[browser_urlbar_stop_pending.js]
support-files =
slow-page.sjs
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/urlbar/browser_urlbar_locationchange_urlbar_edit_dos.js
@@ -0,0 +1,41 @@
+"use strict";
+
+function* checkURLBarValueStays(browser) {
+ gURLBar.select();
+ EventUtils.synthesizeKey("a", {});
+ is(gURLBar.value, "a", "URL bar value should match after sending a key");
+ yield new Promise(resolve => {
+ let listener = {
+ onLocationChange(aWebProgress, aRequest, aLocation, aFlags) {
+ ok(aFlags & Ci.nsIWebProgressListener.LOCATION_CHANGE_SAME_DOCUMENT,
+ "Should only get a same document location change");
+ gBrowser.selectedBrowser.removeProgressListener(filter);
+ filter = null;
+ resolve();
+ },
+ };
+ let filter = Cc["@mozilla.org/appshell/component/browser-status-filter;1"]
+ .createInstance(Ci.nsIWebProgress);
+ filter.addProgressListener(listener, Ci.nsIWebProgress.NOTIFY_ALL);
+ gBrowser.selectedBrowser.addProgressListener(filter);
+ });
+ is(gURLBar.value, "a", "URL bar should not have been changed by location changes.");
+}
+
+add_task(function*() {
+ yield BrowserTestUtils.withNewTab({
+ gBrowser,
+ url: "http://example.com/browser/browser/base/content/test/urlbar/file_urlbar_edit_dos.html"
+ }, function*(browser) {
+ yield ContentTask.spawn(browser, "", function() {
+ content.wrappedJSObject.dos_hash();
+ });
+ yield checkURLBarValueStays(browser);
+ yield ContentTask.spawn(browser, "", function() {
+ content.clearTimeout(content.wrappedJSObject.dos_timeout);
+ content.wrappedJSObject.dos_pushState();
+ });
+ yield checkURLBarValueStays(browser);
+ });
+});
+
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/urlbar/file_urlbar_edit_dos.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>Try editing the URL bar</title>
+<meta http-equiv="Content-Type" content="text/html;charset=utf-8"></meta>
+</head>
+<body>
+<script>
+var dos_timeout = null;
+function dos_hash() {
+ dos_timeout = setTimeout(function() {
+ location.hash = "#";
+ }, 50);
+}
+
+function dos_pushState() {
+ dos_timeout = setTimeout(function() {
+ history.pushState({}, "Some title", "");
+ }, 50);
+}
+</script>
+</body>
+</html>
--- a/toolkit/content/browser-child.js
+++ b/toolkit/content/browser-child.js
@@ -125,19 +125,19 @@ var WebProgressListener = {
// It's possible that this state change was triggered by
// loading an internal error page, for which the parent
// will want to know some details, so we'll update it with
// the documentURI.
if (aWebProgress && aWebProgress.isTopLevel) {
json.documentURI = content.document.documentURIObject.spec;
json.charset = content.document.characterSet;
json.mayEnableCharacterEncodingMenu = docShell.mayEnableCharacterEncodingMenu;
+ json.inLoadURI = WebNavigation.inLoadURI;
}
- json.inLoadURI = WebNavigation.inLoadURI;
this._send("Content:StateChange", json, objects);
},
onProgressChange: function onProgressChange(aWebProgress, aRequest, aCurSelf, aMaxSelf, aCurTotal, aMaxTotal) {
let json = this._setupJSON(aWebProgress, aRequest);
let objects = this._setupObjects(aWebProgress, aRequest);
json.curSelf = aCurSelf;
@@ -166,16 +166,17 @@ var WebProgressListener = {
if (aWebProgress && aWebProgress.isTopLevel) {
json.documentURI = content.document.documentURIObject.spec;
json.title = content.document.title;
json.charset = content.document.characterSet;
json.mayEnableCharacterEncodingMenu = docShell.mayEnableCharacterEncodingMenu;
json.principal = content.document.nodePrincipal;
json.synthetic = content.document.mozSyntheticDocument;
+ json.inLoadURI = WebNavigation.inLoadURI;
if (AppConstants.MOZ_CRASHREPORTER && CrashReporter.enabled) {
let uri = aLocationURI.clone();
try {
// If the current URI contains a username/password, remove it.
uri.userPass = "";
} catch (ex) { /* Ignore failures on about: URIs. */ }
CrashReporter.annotateCrashReport("URL", uri.spec);
--- a/toolkit/modules/RemoteWebProgress.jsm
+++ b/toolkit/modules/RemoteWebProgress.jsm
@@ -215,17 +215,19 @@ RemoteWebProgressManager.prototype = {
request = new RemoteWebProgressRequest(json.requestURI,
json.originalRequestURI,
objects.request);
}
if (isTopLevel) {
this._browser._contentWindow = objects.contentWindow;
this._browser._documentContentType = json.documentContentType;
- this._browser.inLoadURI = json.inLoadURI;
+ if (typeof json.inLoadURI != "undefined") {
+ this._browser.inLoadURI = json.inLoadURI;
+ }
if (json.charset) {
this._browser._characterSet = json.charset;
this._browser._mayEnableCharacterEncodingMenu = json.mayEnableCharacterEncodingMenu;
}
}
switch (aMessage.name) {
case "Content:StateChange":