зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1456035: Follow-up: Delete redundant test_extensionURL.html, which fails with wrapper errors. r=me f=aswan CLOSED TREE
MozReview-Commit-ID: F5LmwfizygB --HG-- extra : amend_source : 478bc62294f7a311f960a0b3e888261473254d15
This commit is contained in:
Родитель
1e0138caf3
Коммит
fc4672bb17
|
@ -13,4 +13,3 @@ support-files =
|
||||||
[test_bug470804.html]
|
[test_bug470804.html]
|
||||||
[test_bug1367586.html]
|
[test_bug1367586.html]
|
||||||
[test_disallowInheritPrincipal.html]
|
[test_disallowInheritPrincipal.html]
|
||||||
[test_extensionURL.html]
|
|
||||||
|
|
|
@ -1,290 +0,0 @@
|
||||||
<!DOCTYPE HTML>
|
|
||||||
<html>
|
|
||||||
<!--
|
|
||||||
https://bugzilla.mozilla.org/show_bug.cgi?id=1161831
|
|
||||||
-->
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<title>Test for Bug 1161831</title>
|
|
||||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
|
||||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
|
||||||
<script type="application/javascript">
|
|
||||||
|
|
||||||
/** Test for Bug 1161831 **/
|
|
||||||
SimpleTest.waitForExplicitFinish();
|
|
||||||
|
|
||||||
let module = SpecialPowers.Cu.getGlobalForObject(SpecialPowers.Cu.import("resource://gre/modules/Services.jsm", {}));
|
|
||||||
var {MatchGlob, MatchPatternSet, WebExtensionPolicy} = module;
|
|
||||||
|
|
||||||
var policy1, policy2;
|
|
||||||
|
|
||||||
var XPCOMUtils = SpecialPowers.Cu.import("resource://gre/modules/XPCOMUtils.jsm").XPCOMUtils;
|
|
||||||
var resourceHandler = SpecialPowers.Services.io.getProtocolHandler("resource")
|
|
||||||
.QueryInterface(SpecialPowers.Ci.nsISubstitutingProtocolHandler);
|
|
||||||
var extensionHandler = SpecialPowers.Services.io.getProtocolHandler("moz-extension")
|
|
||||||
.QueryInterface(SpecialPowers.Ci.nsISubstitutingProtocolHandler);
|
|
||||||
var fileHandler = SpecialPowers.Cc["@mozilla.org/network/protocol;1?name=file"]
|
|
||||||
.getService(SpecialPowers.Ci.nsIFileProtocolHandler);
|
|
||||||
|
|
||||||
// Chrome script that adds handles for inserting substitutions and
|
|
||||||
// resolving symlinked paths in the parent process.
|
|
||||||
var script = SpecialPowers.loadChromeScript(() => {
|
|
||||||
ChromeUtils.import("resource://gre/modules/Services.jsm");
|
|
||||||
|
|
||||||
// Sets up a substitution in the parent process
|
|
||||||
this.addMessageListener("SetSubstitution", ({from, to}) => {
|
|
||||||
// Convert the passed |to| string to a URI.
|
|
||||||
// A null |to| value clears the substitution
|
|
||||||
if (to != null) {
|
|
||||||
var uri = Services.io.newURI(to);
|
|
||||||
}
|
|
||||||
Services.io.getProtocolHandler("moz-extension")
|
|
||||||
.QueryInterface(Ci.nsISubstitutingProtocolHandler)
|
|
||||||
.setSubstitution(from, uri);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Gets a normalized (de-symlinked) path in the parent process
|
|
||||||
this.addMessageListener("ResolvePath", (path) => {
|
|
||||||
let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
|
|
||||||
file.initWithPath(path);
|
|
||||||
file.normalize();
|
|
||||||
return file.path;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// An array of objects each containing a callback and a host
|
|
||||||
// for a substitution that has been set in either the parent
|
|
||||||
// or local child process and for which we are waiting for the
|
|
||||||
// observer notification in the child process.
|
|
||||||
var pendingSubstitutions = [];
|
|
||||||
|
|
||||||
// Adds a new callback to |pendingSubstitutions|.
|
|
||||||
function pushSubstitutionCallback(callback, host) {
|
|
||||||
let entry = {callback, host};
|
|
||||||
pendingSubstitutions.push(entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Invoke the first callback found in |pendingSubstitutions|
|
|
||||||
// with a matching host.
|
|
||||||
function popSubstitutionCallback(host) {
|
|
||||||
for (let i = 0; i < pendingSubstitutions.length; i++) {
|
|
||||||
let entry = pendingSubstitutions[i];
|
|
||||||
if (host === entry.host) {
|
|
||||||
entry.callback();
|
|
||||||
pendingSubstitutions.splice(i, 1);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// This indicates we installed a mapping in either the
|
|
||||||
// parent or the local child process, but never received an
|
|
||||||
// observer notification in the child for a mapping with
|
|
||||||
// a matching host.
|
|
||||||
ok(false, `popSubstitutionCallback(${host}) no match found`);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Define an implementation of nsISubstitutionObserver and add it
|
|
||||||
// to this process' ExtensionProtocolHandler to observe substitutions
|
|
||||||
// as they are propagated to the child.
|
|
||||||
function SubstitutionObserver() {}
|
|
||||||
SubstitutionObserver.prototype = {
|
|
||||||
onSetSubstitution: SpecialPowers.wrapCallback(function(root, uri) {
|
|
||||||
popSubstitutionCallback(root);
|
|
||||||
}),
|
|
||||||
QueryInterface:
|
|
||||||
XPCOMUtils.generateQI([SpecialPowers.Ci.nsISupports,
|
|
||||||
SpecialPowers.Ci.nsISubstitutionObserver]),
|
|
||||||
};
|
|
||||||
var observer = new SubstitutionObserver();
|
|
||||||
var wrappedObserver = SpecialPowers.wrap(observer);
|
|
||||||
extensionHandler.addObserver(wrappedObserver);
|
|
||||||
|
|
||||||
// Set a substitution in the parent. The parent
|
|
||||||
// propagates all substitutions to child processes.
|
|
||||||
function globalSetSubstitution(chromeScript, from, to) {
|
|
||||||
var p = new Promise(function(resolve, reject) {
|
|
||||||
pushSubstitutionCallback(resolve, from);
|
|
||||||
chromeScript.sendSyncMessage("SetSubstitution", {from, to});
|
|
||||||
});
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
SimpleTest.registerCleanupFunction(function() {
|
|
||||||
extensionHandler.removeObserver(wrappedObserver);
|
|
||||||
policy1.active = false;
|
|
||||||
policy2.active = false;
|
|
||||||
script.sendSyncMessage("SetSubstitution", {from: "cherise", to: null});
|
|
||||||
script.sendSyncMessage("SetSubstitution", {from: "liebchen", to: null});
|
|
||||||
});
|
|
||||||
|
|
||||||
addLoadEvent(function() {
|
|
||||||
|
|
||||||
// First, get a file:// URI to something - open to suggestions on how to do
|
|
||||||
// this more easily.
|
|
||||||
var resURI = SpecialPowers.Services.io.newURI("resource://testing-common/resource_test_file.html");
|
|
||||||
var filePath = resourceHandler.resolveURI(resURI);
|
|
||||||
ok(filePath.startsWith("file://"), "resource:// URI resolves where we expect: " + filePath);
|
|
||||||
var resFile = fileHandler.getFileFromURLSpec(filePath);
|
|
||||||
|
|
||||||
// Get normalized path to the test file. We already have a file object
|
|
||||||
// |resFile|, but its underlying path may contain a symlink we can't
|
|
||||||
// resolve in the child process.
|
|
||||||
let resolvedPath = script.sendSyncMessage("ResolvePath", resFile.path);
|
|
||||||
let file = SpecialPowers.Cc["@mozilla.org/file/local;1"]
|
|
||||||
.createInstance(SpecialPowers.Ci.nsIFile);
|
|
||||||
info(`resolved test file path: ${resolvedPath}`);
|
|
||||||
file.initWithPath(resolvedPath);
|
|
||||||
|
|
||||||
// Setup the base directory URI string and a URI string to refer to
|
|
||||||
// the test file within that directory.
|
|
||||||
let cheriseURIStr = "moz-extension://cherise/" + file.leafName;
|
|
||||||
let liebchenURIStr = "moz-extension://liebchen/" + file.leafName;
|
|
||||||
let cheriseBaseDirURIStr = "file://" + file.parent.path + "/";
|
|
||||||
info(`cheriseURIStr: ${cheriseURIStr}`);
|
|
||||||
info(`liebchenURIStr: ${liebchenURIStr}`);
|
|
||||||
info(`cheriseBaseDirURIStr: ${cheriseBaseDirURIStr}`);
|
|
||||||
|
|
||||||
function StubPolicy(id, accessible) {
|
|
||||||
let policy = new WebExtensionPolicy(SpecialPowers.Cu.cloneInto({
|
|
||||||
id: `imaginaryaddon-${id[0]}`,
|
|
||||||
mozExtensionHostname: id,
|
|
||||||
baseURL: cheriseBaseDirURIStr,
|
|
||||||
|
|
||||||
allowedOrigins: SpecialPowers.unwrap(new MatchPatternSet([])),
|
|
||||||
webAccessibleResources: accessible ? [SpecialPowers.unwrap(new MatchGlob("*"))] : [],
|
|
||||||
localizeCallback(string) {},
|
|
||||||
}, module, {cloneFunctions: true, wrapReflectors: true}));
|
|
||||||
|
|
||||||
// Activating the policy results in a substitution being added,
|
|
||||||
// which triggers SubstitutionObserver.onSetSubstitution().
|
|
||||||
// All observer notifications must be accounted for (in this
|
|
||||||
// test to validate they are working correctly) so ignore this
|
|
||||||
// substitution when the observer gets notified.
|
|
||||||
pushSubstitutionCallback(() => {}, id);
|
|
||||||
policy.active = true;
|
|
||||||
return policy;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Register a moz-extension:// URI locally.
|
|
||||||
policy1 = StubPolicy("cherise", false);
|
|
||||||
policy2 = StubPolicy("liebchen", false);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Make sure that non-file:// URIs don't work.
|
|
||||||
//
|
|
||||||
|
|
||||||
// resource://
|
|
||||||
try {
|
|
||||||
extensionHandler.setSubstitution("interdit", resURI);
|
|
||||||
ok(false, "Should have thrown for mapping moz-extension to resource");
|
|
||||||
} catch (e) {
|
|
||||||
ok(true, "Threw correctly: " + e);
|
|
||||||
}
|
|
||||||
|
|
||||||
// chrome://
|
|
||||||
try {
|
|
||||||
var chromeURI = SpecialPowers.Services.io.newURI("chrome://global/content/mozilla.xhtml");
|
|
||||||
extensionHandler.setSubstitution("verboten", chromeURI);
|
|
||||||
ok(false, "Should have thrown for mapping moz-extension to chrome");
|
|
||||||
} catch (e) {
|
|
||||||
ok(true, "Threw correctly: " + e);
|
|
||||||
}
|
|
||||||
|
|
||||||
function navigateWithLocation(ifr, url) { ifr.contentWindow.location = url; }
|
|
||||||
function navigateWithSrc(ifr, url) { ifr.setAttribute("src", url); }
|
|
||||||
function navigateFromChromeWithLocation(ifr, url) { SpecialPowers.wrap(ifr).contentWindow.location = url; }
|
|
||||||
function navigateFromChromeWithWebNav(ifr, url) {
|
|
||||||
SpecialPowers.wrap(ifr).contentWindow
|
|
||||||
.QueryInterface(SpecialPowers.Ci.nsIInterfaceRequestor)
|
|
||||||
.getInterface(SpecialPowers.Ci.nsIWebNavigation)
|
|
||||||
.loadURI(url, 0, null, null, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function setWhitelistCallback(paths) {
|
|
||||||
pushSubstitutionCallback(() => {}, policy1.mozExtensionHostname);
|
|
||||||
policy1.active = false;
|
|
||||||
|
|
||||||
pushSubstitutionCallback(() => {}, policy2.mozExtensionHostname);
|
|
||||||
policy2.active = false;
|
|
||||||
|
|
||||||
policy1 = StubPolicy("cherise", paths.includes("cherise"));
|
|
||||||
policy2 = StubPolicy("liebchen", paths.includes("liebchen"));
|
|
||||||
}
|
|
||||||
|
|
||||||
function testLoad(url, navigate, shouldThrow) {
|
|
||||||
var ifr = document.createElement("iframe");
|
|
||||||
var p = new Promise(function(resolve, reject) {
|
|
||||||
ifr.onload = function() {
|
|
||||||
ok(true, "Loaded " + url);
|
|
||||||
var prin = SpecialPowers.wrap(ifr.contentWindow).document.nodePrincipal;
|
|
||||||
function stripTrailingSlash(s) { return s.replace(/\/$/, ""); }
|
|
||||||
is(stripTrailingSlash(prin.URI.spec), url, "Principal uri is correct: " + url);
|
|
||||||
function stripPath(s) { return s.replace(/(.*\/\/.+)\/.*/, "$1"); }
|
|
||||||
is(prin.originNoSuffix, stripPath(url), "Principal origin is correct: " + prin.originNoSuffix);
|
|
||||||
is(prin.addonId, "imaginaryaddon-" + url[url.indexOf("/") + 2], "addonId is correct");
|
|
||||||
is(SpecialPowers.wrap(ifr.contentWindow).document.title, "resource test file",
|
|
||||||
"document looks right");
|
|
||||||
ifr.remove();
|
|
||||||
resolve();
|
|
||||||
};
|
|
||||||
document.body.appendChild(ifr);
|
|
||||||
|
|
||||||
var threw = false;
|
|
||||||
try {
|
|
||||||
navigate(ifr, url);
|
|
||||||
} catch (e) {
|
|
||||||
ifr.remove();
|
|
||||||
threw = true;
|
|
||||||
ok(/denied|insecure/.test(e), "exception correct: " + e);
|
|
||||||
}
|
|
||||||
is(threw, !!shouldThrow, "Correct throwing behavior for: " + url);
|
|
||||||
!threw || resolve();
|
|
||||||
});
|
|
||||||
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
function testXHR(url, shouldError) {
|
|
||||||
return new Promise(function(resolve, reject) {
|
|
||||||
var xhr = new XMLHttpRequest();
|
|
||||||
xhr.addEventListener("load", () => { ok(!shouldError, `XHR to ${url} should succeed`); resolve(); });
|
|
||||||
xhr.addEventListener("error", () => { ok(shouldError, `XHR to ${url} should fail`); resolve(); });
|
|
||||||
xhr.open("GET", url, true);
|
|
||||||
xhr.send();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Perform some loads and make sure they work correctly.
|
|
||||||
//
|
|
||||||
globalSetSubstitution(script, "cherise", cheriseBaseDirURIStr)
|
|
||||||
.then(testLoad.bind(null, cheriseURIStr, navigateFromChromeWithLocation))
|
|
||||||
.then(testLoad.bind(null, cheriseURIStr, navigateFromChromeWithWebNav))
|
|
||||||
.then(testLoad.bind(null, cheriseURIStr, navigateWithLocation, /* shouldThrow = */ true))
|
|
||||||
.then(testXHR.bind(null, cheriseURIStr, /* shouldError = */ true))
|
|
||||||
.then(setWhitelistCallback.bind(null, ["cherise"]))
|
|
||||||
.then(testLoad.bind(null, cheriseURIStr, navigateWithLocation))
|
|
||||||
.then(testXHR.bind(null, cheriseURIStr))
|
|
||||||
.then(globalSetSubstitution(script, "liebchen", "moz-extension://cherise"))
|
|
||||||
.then(testLoad.bind(null, liebchenURIStr, navigateWithLocation, /* shouldThrow = */ true))
|
|
||||||
.then(testXHR.bind(null, liebchenURIStr, /* shouldError = */ true))
|
|
||||||
.then(setWhitelistCallback.bind(null, ["cherise", "liebchen"]))
|
|
||||||
.then(testLoad.bind(null, liebchenURIStr, navigateWithLocation))
|
|
||||||
.then(testLoad.bind(null, liebchenURIStr, navigateWithSrc))
|
|
||||||
.then(testLoad.bind(null, cheriseURIStr, navigateWithSrc))
|
|
||||||
.then(SimpleTest.finish.bind(SimpleTest),
|
|
||||||
function(e) { ok(false, "rejected promise: " + e); SimpleTest.finish(); }
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
</script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1161831">Mozilla Bug 1161831</a>
|
|
||||||
<p id="display"></p>
|
|
||||||
<div id="content" style="display: none">
|
|
||||||
</div>
|
|
||||||
<pre id="test">
|
|
||||||
</pre>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
Загрузка…
Ссылка в новой задаче