Bug 1034845 - Re-enable pasting data URIs to the location bar. r=gijs

--HG--
extra : rebase_source : e03b3d39e47dd1c917e0e343621d8c51f500685e
This commit is contained in:
Dão Gottwald 2014-07-11 00:39:55 +02:00
parent ba4ae2ee67
commit f72e42203b
8 changed files with 128 additions and 48 deletions

View File

@ -1913,6 +1913,7 @@ function loadURI(uri, referrer, postData, allowThirdPartyFixup) {
}
function getShortcutOrURIAndPostData(aURL, aCallback) {
let mayInheritPrincipal = false;
let postData = null;
let shortcutURL = null;
let keyword = aURL;
@ -1928,7 +1929,8 @@ function getShortcutOrURIAndPostData(aURL, aCallback) {
if (engine) {
let submission = engine.getSubmission(param);
postData = submission.postData;
aCallback({ postData: submission.postData, url: submission.uri.spec });
aCallback({ postData: submission.postData, url: submission.uri.spec,
mayInheritPrincipal: mayInheritPrincipal });
return;
}
@ -1936,7 +1938,8 @@ function getShortcutOrURIAndPostData(aURL, aCallback) {
PlacesUtils.getURLAndPostDataForKeyword(keyword);
if (!shortcutURL) {
aCallback({ postData: postData, url: aURL });
aCallback({ postData: postData, url: aURL,
mayInheritPrincipal: mayInheritPrincipal });
return;
}
@ -1968,7 +1971,12 @@ function getShortcutOrURIAndPostData(aURL, aCallback) {
postData = getPostDataStream(escapedPostData, param, encodedParam,
"application/x-www-form-urlencoded");
aCallback({ postData: postData, url: shortcutURL });
// This URL came from a bookmark, so it's safe to let it inherit the current
// document's principal.
mayInheritPrincipal = true;
aCallback({ postData: postData, url: shortcutURL,
mayInheritPrincipal: mayInheritPrincipal });
}
if (matches) {
@ -1991,9 +1999,15 @@ function getShortcutOrURIAndPostData(aURL, aCallback) {
// the original URL.
postData = null;
aCallback({ postData: postData, url: aURL });
aCallback({ postData: postData, url: aURL,
mayInheritPrincipal: mayInheritPrincipal });
} else {
aCallback({ postData: postData, url: shortcutURL });
// This URL came from a bookmark, so it's safe to let it inherit the current
// document's principal.
mayInheritPrincipal = true;
aCallback({ postData: postData, url: shortcutURL,
mayInheritPrincipal: mayInheritPrincipal });
}
}
@ -5181,7 +5195,8 @@ function middleMousePaste(event) {
if (where != "current" ||
lastLocationChange == gBrowser.selectedBrowser.lastLocationChange) {
openUILink(data.url, event,
{ ignoreButton: true });
{ ignoreButton: true,
disallowInheritPrincipal: !data.mayInheritPrincipal });
}
});
@ -5189,26 +5204,9 @@ function middleMousePaste(event) {
}
function stripUnsafeProtocolOnPaste(pasteData) {
// Don't allow pasting in full URIs which inherit the security context.
const URI_INHERITS_SECURITY_CONTEXT = Ci.nsIProtocolHandler.URI_INHERITS_SECURITY_CONTEXT;
let pastedURI;
try {
pastedURI = makeURI(pasteData.trim());
} catch (ex) {
return pasteData;
}
while (Services.netutil.URIChainHasFlags(pastedURI, URI_INHERITS_SECURITY_CONTEXT)) {
pasteData = pastedURI.path.trim();
try {
pastedURI = makeURI(pasteData);
} catch (ex) {
break;
}
}
return pasteData;
// Don't allow pasting javascript URIs since we don't support
// LOAD_FLAGS_DISALLOW_INHERIT_OWNER for those.
return pasteData.replace(/^(?:\s*javascript:)+/i, "");
}
function handleDroppedLink(event, url, name)

View File

@ -313,6 +313,7 @@ skip-if = e10s # Bug ?????? - test directly manipulates content (gBrowser.conten
skip-if = toolkit == "windows" # Disabled on Windows due to frequent failures (bug 969405)
[browser_locationBarCommand.js]
skip-if = os == "linux" || e10s # Linux: Intermittent failures, bug 917535; e10s: Bug ?????? - Focus issues (There should be no focused element - Got [object XULElement], expected null)
[browser_locationBarExternalLoad.js]
[browser_menuButtonFitts.js]
skip-if = os != "win" || e10s # The Fitts Law menu button is only supported on Windows (bug 969376); # Bug ?????? - URL bar issues ("There should be no focused element - Got [object XULElement], expected null")
[browser_middleMouse_noJSPaste.js]

View File

@ -11,9 +11,10 @@ function getPostDataString(aIS) {
return dataLines[dataLines.length-1];
}
function keywordResult(aURL, aPostData) {
function keywordResult(aURL, aPostData, aIsUnsafe) {
this.url = aURL;
this.postData = aPostData;
this.isUnsafe = aIsUnsafe;
}
function keyWordData() {}
@ -52,20 +53,20 @@ var testData = [
new keywordResult("http://bmget-nosearch/", null)],
[new searchKeywordData("searchget", "http://searchget/?search={searchTerms}", null, "foo4"),
new keywordResult("http://searchget/?search=foo4", null)],
new keywordResult("http://searchget/?search=foo4", null, true)],
[new searchKeywordData("searchpost", "http://searchpost/", "search={searchTerms}", "foo5"),
new keywordResult("http://searchpost/", "search=foo5")],
new keywordResult("http://searchpost/", "search=foo5", true)],
[new searchKeywordData("searchpostget", "http://searchpostget/?search1={searchTerms}", "search2={searchTerms}", "foo6"),
new keywordResult("http://searchpostget/?search1=foo6", "search2=foo6")],
new keywordResult("http://searchpostget/?search1=foo6", "search2=foo6", true)],
// Bookmark keywords that don't take parameters should not be activated if a
// parameter is passed (bug 420328).
[new bmKeywordData("bmget-noparam", "http://bmget-noparam/", null, "foo7"),
new keywordResult(null, null)],
new keywordResult(null, null, true)],
[new bmKeywordData("bmpost-noparam", "http://bmpost-noparam/", "not_a=param", "foo8"),
new keywordResult(null, null)],
new keywordResult(null, null, true)],
// Test escaping (%s = escaped, %S = raw)
// UTF-8 default
@ -87,7 +88,7 @@ var testData = [
// getShortcutOrURIAndPostData for non-keywords (setupKeywords only adds keywords for
// bmKeywordData objects)
[{keyword: "http://gavinsharp.com"},
new keywordResult(null, null)]
new keywordResult(null, null, true)]
];
function test() {
@ -108,6 +109,7 @@ function test() {
let expected = result.url || query;
is(returnedData.url, expected, "got correct URL for " + data.keyword);
is(getPostDataString(returnedData.postData), result.postData, "got correct postData for " + data.keyword);
is(returnedData.mayInheritPrincipal, !result.isUnsafe, "got correct mayInheritPrincipal for " + data.keyword);
}
cleanupKeywords();
}).then(finish);

View File

@ -0,0 +1,64 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
function test() {
waitForExplicitFinish();
nextTest();
}
let urls = [
"data:text/html,<body>hi"
];
function urlEnter(url) {
gURLBar.value = url;
gURLBar.focus();
EventUtils.synthesizeKey("VK_RETURN", {});
}
function urlClick(url) {
gURLBar.value = url;
gURLBar.focus();
let goButton = document.getElementById("urlbar-go-button");
EventUtils.synthesizeMouseAtCenter(goButton, {});
}
function nextTest() {
let url = urls.shift();
if (url) {
testURL(url, urlEnter, function () {
testURL(url, urlClick, nextTest);
});
}
else
finish();
}
function testURL(url, loadFunc, endFunc) {
let tab = gBrowser.selectedTab = gBrowser.addTab();
registerCleanupFunction(function () {
gBrowser.removeTab(tab);
});
addPageShowListener(function () {
let pagePrincipal = gBrowser.contentPrincipal;
loadFunc(url);
addPageShowListener(function () {
let fm = Cc["@mozilla.org/focus-manager;1"].getService(Ci.nsIFocusManager);
is(fm.focusedElement, null, "should be no focused element");
is(fm.focusedWindow, gBrowser.contentWindow, "content window should be focused");
ok(!gBrowser.contentPrincipal.equals(pagePrincipal),
"load of " + url + " by " + loadFunc.name + " should produce a page with a different principal");
endFunc();
});
});
}
function addPageShowListener(func) {
gBrowser.selectedBrowser.addEventListener("pageshow", function loadListener() {
gBrowser.selectedBrowser.removeEventListener("pageshow", loadListener, false);
func();
});
}

View File

@ -7,13 +7,13 @@ let pairs = [
["javascript:", ""],
["javascript:1+1", "1+1"],
["javascript:document.domain", "document.domain"],
["data:text/html,<body>hi</body>", "text/html,<body>hi</body>"],
["data:text/html,<body>hi</body>", "data:text/html,<body>hi</body>"],
// Nested things get confusing because some things don't parse as URIs:
["javascript:javascript:alert('hi!')", "alert('hi!')"],
["data:data:text/html,<body>hi</body>", "text/html,<body>hi</body>"],
["data:data:text/html,<body>hi</body>", "data:data:text/html,<body>hi</body>"],
["javascript:data:javascript:alert('hi!')", "data:javascript:alert('hi!')"],
["javascript:data:text/html,javascript:alert('hi!')", "text/html,javascript:alert('hi!')"],
["data:data:text/html,javascript:alert('hi!')", "text/html,javascript:alert('hi!')"],
["javascript:data:text/html,javascript:alert('hi!')", "data:text/html,javascript:alert('hi!')"],
["data:data:text/html,javascript:alert('hi!')", "data:data:text/html,javascript:alert('hi!')"],
];
let clipboardHelper = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper);

View File

@ -265,6 +265,7 @@
return; // Do nothing for right clicks
var url = this.value;
var mayInheritPrincipal = false;
var postData = null;
var action = this._parseActionUrl(url);
@ -287,7 +288,7 @@
}
else {
this._canonizeURL(aTriggeringEvent, response => {
[url, postData] = response;
[url, postData, mayInheritPrincipal] = response;
if (url) {
matchLastLocationChange = (lastLocationChange ==
gBrowser.selectedBrowser.lastLocationChange);
@ -309,10 +310,11 @@
}
function loadCurrent() {
let webnav = Ci.nsIWebNavigation;
let flags = webnav.LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP |
webnav.LOAD_FLAGS_FIXUP_SCHEME_TYPOS;
gBrowser.loadURIWithFlags(url, flags, null, null, postData);
openUILinkIn(url, "current", {
allowThirdPartyFixup: true,
disallowInheritPrincipal: !mayInheritPrincipal,
postData: postData
});
}
// Focus the content area before triggering loads, since if the load
@ -422,7 +424,7 @@
}
getShortcutOrURIAndPostData(url, data => {
aCallback([data.url, data.postData]);
aCallback([data.url, data.postData, data.mayInheritPrincipal]);
});
]]></body>
</method>

View File

@ -281,11 +281,18 @@ function openLinkIn(url, where, params) {
getBoolPref("browser.tabs.loadInBackground");
}
let uriObj;
if (where == "current") {
try {
uriObj = Services.io.newURI(url, null, null);
} catch (e) {}
}
if (where == "current" && w.gBrowser.selectedTab.pinned) {
try {
let uriObj = Services.io.newURI(url, null, null);
if (!uriObj.schemeIs("javascript") &&
w.gBrowser.currentURI.host != uriObj.host) {
// nsIURI.host can throw for non-nsStandardURL nsIURIs.
if (!uriObj || (!uriObj.schemeIs("javascript") &&
w.gBrowser.currentURI.host != uriObj.host)) {
where = "tab";
loadInBackground = false;
}
@ -302,12 +309,19 @@ function openLinkIn(url, where, params) {
switch (where) {
case "current":
let flags = Ci.nsIWebNavigation.LOAD_FLAGS_NONE;
if (aAllowThirdPartyFixup) {
flags |= Ci.nsIWebNavigation.LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP;
flags |= Ci.nsIWebNavigation.LOAD_FLAGS_FIXUP_SCHEME_TYPOS;
}
if (aDisallowInheritPrincipal)
// LOAD_FLAGS_DISALLOW_INHERIT_OWNER isn't supported for javascript URIs,
// i.e. it causes them not to load at all. Callers should strip
// "javascript:" from pasted strings to protect users from malicious URIs
// (see stripUnsafeProtocolOnPaste).
if (aDisallowInheritPrincipal && !(uriObj && uriObj.schemeIs("javascript")))
flags |= Ci.nsIWebNavigation.LOAD_FLAGS_DISALLOW_INHERIT_OWNER;
w.gBrowser.loadURIWithFlags(url, flags, aReferrerURI, null, aPostData);
break;
case "tabshifted":

View File

@ -61,7 +61,6 @@ let initTable = [
["io", "@mozilla.org/network/io-service;1", "nsIIOService2"],
["locale", "@mozilla.org/intl/nslocaleservice;1", "nsILocaleService"],
["logins", "@mozilla.org/login-manager;1", "nsILoginManager"],
["netutil", "@mozilla.org/network/util;1", "nsINetUtil"],
["obs", "@mozilla.org/observer-service;1", "nsIObserverService"],
["perms", "@mozilla.org/permissionmanager;1", "nsIPermissionManager"],
["prompt", "@mozilla.org/embedcomp/prompt-service;1", "nsIPromptService"],