зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1511483 - pageAction show_matches/hide_matches should allow unrestricted schemes on privileged mozilla addons. r=mixedpuppy
Differential Revision: https://phabricator.services.mozilla.com/D13582 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
e027ad57e6
Коммит
dfbc857688
|
@ -55,8 +55,9 @@ this.pageAction = class extends ExtensionAPI {
|
|||
show = false;
|
||||
} else {
|
||||
// Might show or hide depending on the URL. Enable pattern matching.
|
||||
showMatches = new MatchPatternSet(show_matches);
|
||||
hideMatches = new MatchPatternSet(hide_matches);
|
||||
const {restrictSchemes} = extension;
|
||||
showMatches = new MatchPatternSet(show_matches, {restrictSchemes});
|
||||
hideMatches = new MatchPatternSet(hide_matches, {restrictSchemes});
|
||||
}
|
||||
|
||||
this.defaults = {
|
||||
|
|
|
@ -175,3 +175,63 @@ add_task(async function test_pageAction_all_urls() {
|
|||
let rejects = await extension.startup().then(() => false, () => true);
|
||||
is(rejects, true, "startup failed");
|
||||
});
|
||||
|
||||
add_task(async function test_pageAction_restrictScheme_false() {
|
||||
info("Check restricted origins are allowed in show_matches for privileged extensions");
|
||||
let extension = ExtensionTestUtils.loadExtension({
|
||||
isPrivileged: true,
|
||||
manifest: {
|
||||
permissions: ["mozillaAddons", "tabs"],
|
||||
page_action: {
|
||||
"show_matches": ["about:reader*"],
|
||||
"hide_matches": ["*://*/*"],
|
||||
},
|
||||
},
|
||||
background: function() {
|
||||
browser.tabs.onUpdated.addListener(async (tabId, changeInfo) => {
|
||||
if (changeInfo.url && changeInfo.url.startsWith("about:reader")) {
|
||||
browser.test.sendMessage("readerModeEntered");
|
||||
}
|
||||
});
|
||||
|
||||
browser.test.onMessage.addListener(async (msg) => {
|
||||
if (msg !== "enterReaderMode") {
|
||||
browser.test.fail(`Received unexpected test message: ${msg}`);
|
||||
return;
|
||||
}
|
||||
|
||||
browser.tabs.toggleReaderMode();
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
async function expectPageAction(extension, tab, isShown) {
|
||||
await promiseAnimationFrame();
|
||||
let widgetId = makeWidgetId(extension.id);
|
||||
let pageActionId = BrowserPageActions.urlbarButtonNodeIDForActionID(widgetId);
|
||||
let iconEl = document.getElementById(pageActionId);
|
||||
|
||||
if (isShown) {
|
||||
ok(iconEl && !iconEl.hasAttribute("disabled"), "pageAction is shown");
|
||||
} else {
|
||||
ok(iconEl == null || iconEl.getAttribute("disabled") == "true", "pageAction is hidden");
|
||||
}
|
||||
}
|
||||
|
||||
const baseUrl = getRootDirectory(gTestPath).replace("chrome://mochitests/content", "http://example.com");
|
||||
const url = `${baseUrl}/readerModeArticle.html`;
|
||||
let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, url, true, true);
|
||||
|
||||
await extension.startup();
|
||||
|
||||
await expectPageAction(extension, tab, false);
|
||||
|
||||
extension.sendMessage("enterReaderMode");
|
||||
await extension.awaitMessage("readerModeEntered");
|
||||
|
||||
await expectPageAction(extension, tab, true);
|
||||
|
||||
BrowserTestUtils.removeTab(tab);
|
||||
|
||||
await extension.unload();
|
||||
});
|
||||
|
|
|
@ -467,6 +467,13 @@ class ExtensionData {
|
|||
});
|
||||
}
|
||||
|
||||
get restrictSchemes() {
|
||||
// ExtensionData can't check the signature (as it is not yet passed to its constructor
|
||||
// as it is for the Extension class, where this getter is overridden to check both the
|
||||
// signature and the permissions).
|
||||
return !this.hasPermission("mozillaAddons");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an object representing any capabilities that the extension
|
||||
* has access to based on fixed properties in the manifest. The result
|
||||
|
@ -481,7 +488,7 @@ class ExtensionData {
|
|||
|
||||
let permissions = new Set();
|
||||
let origins = new Set();
|
||||
let restrictSchemes = !this.hasPermission("mozillaAddons");
|
||||
let {restrictSchemes} = this;
|
||||
for (let perm of this.manifest.permissions || []) {
|
||||
let type = classifyPermission(perm, restrictSchemes);
|
||||
if (type.origin) {
|
||||
|
@ -858,7 +865,9 @@ class ExtensionData {
|
|||
await this.apiManager.lazyInit();
|
||||
|
||||
this.webAccessibleResources = manifestData.webAccessibleResources.map(res => new MatchGlob(res));
|
||||
this.whiteListedHosts = new MatchPatternSet(manifestData.originPermissions, {restrictSchemes: !this.hasPermission("mozillaAddons")});
|
||||
this.whiteListedHosts = new MatchPatternSet(manifestData.originPermissions, {
|
||||
restrictSchemes: this.restrictSchemes,
|
||||
});
|
||||
|
||||
return this.manifest;
|
||||
}
|
||||
|
@ -1376,8 +1385,10 @@ class Extension extends ExtensionData {
|
|||
if (permissions.origins.length > 0) {
|
||||
let patterns = this.whiteListedHosts.patterns.map(host => host.pattern);
|
||||
|
||||
this.whiteListedHosts = new MatchPatternSet(new Set([...patterns, ...permissions.origins]),
|
||||
{restrictSchemes: !this.hasPermission("mozillaAddons"), ignorePath: true});
|
||||
this.whiteListedHosts = new MatchPatternSet(new Set([...patterns, ...permissions.origins]), {
|
||||
restrictSchemes: this.restrictSchemes,
|
||||
ignorePath: true,
|
||||
});
|
||||
}
|
||||
|
||||
this.policy.permissions = Array.from(this.permissions);
|
||||
|
@ -1406,6 +1417,10 @@ class Extension extends ExtensionData {
|
|||
/* eslint-enable mozilla/balanced-listeners */
|
||||
}
|
||||
|
||||
get restrictSchemes() {
|
||||
return !(this.isPrivileged && this.hasPermission("mozillaAddons"));
|
||||
}
|
||||
|
||||
// Some helpful properties added elsewhere:
|
||||
/**
|
||||
* An object used to map between extension-visible tab ids and
|
||||
|
@ -2015,7 +2030,7 @@ class Extension extends ExtensionData {
|
|||
|
||||
get optionalOrigins() {
|
||||
if (this._optionalOrigins == null) {
|
||||
let restrictSchemes = !this.hasPermission("mozillaAddons");
|
||||
let {restrictSchemes} = this;
|
||||
let origins = this.manifest.optional_permissions.filter(perm => classifyPermission(perm, restrictSchemes).origin);
|
||||
this._optionalOrigins = new MatchPatternSet(origins, {restrictSchemes, ignorePath: true});
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче