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:
Luca Greco 2018-11-30 22:30:39 +00:00
Родитель e027ad57e6
Коммит dfbc857688
3 изменённых файлов: 83 добавлений и 7 удалений

Просмотреть файл

@ -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});
}