Bug 1504018 - Support unrestricted schemes in permission warnings r=aswan

If an extension with the "mozillaAddons" permission is updated, the
permission diffing logic should support restricted schemes.
Otherwise the MatchPattern will throw and prevent the update from being
installed.

`Extension.comparePermissions` is called with the result of
`.userPermissions`, which in turn is equivalent to the result of the
`manifestPermissions` getter. This already filters out restricted
schemes if needed. Therefore we can unconditionally use
`restrictSchemes:false` in `comparePermissions`.

And update the regexp in formatPermissionStrings to support permissions
that start with "about:", since the "MatchPatternUnestricted" type in
toolkit/components/extensions/schemas/manifest.json supports this,
and the lack of "//" in about:-URLs prevents the scheme from being
matched by the existing pattern.

Depends on D14963

Differential Revision: https://phabricator.services.mozilla.com/D14964

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Rob Wu 2019-01-11 19:19:06 +00:00
Родитель 0074eaeaf7
Коммит f8d91f5c26
2 изменённых файлов: 44 добавлений и 6 удалений

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

@ -540,10 +540,10 @@ class ExtensionData {
// Compute the difference between two sets of permissions, suitable
// for presenting to the user.
static comparePermissions(oldPermissions, newPermissions) {
let oldMatcher = new MatchPatternSet(oldPermissions.origins);
let oldMatcher = new MatchPatternSet(oldPermissions.origins, {restrictSchemes: false});
return {
// formatPermissionStrings ignores any scheme, so only look at the domain.
origins: newPermissions.origins.filter(perm => !oldMatcher.subsumesDomain(new MatchPattern(perm))),
origins: newPermissions.origins.filter(perm => !oldMatcher.subsumesDomain(new MatchPattern(perm, {restrictSchemes: false}))),
permissions: newPermissions.permissions.filter(perm => !oldPermissions.permissions.includes(perm)),
};
}
@ -1105,7 +1105,10 @@ class ExtensionData {
allUrls = true;
break;
}
let match = /^[a-z*]+:\/\/([^/]*)\//.exec(permission);
// Privileged extensions may request access to "about:"-URLs, such as
// about:reader.
let match = /^[a-z*]+:\/\/([^/]*)\/|^about:/.exec(permission);
if (!match) {
throw new Error(`Unparseable host permission ${permission}`);
}

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

@ -201,11 +201,11 @@ add_task(async function privileged_with_mozillaAddons() {
let manifestPermissions = await getManifestPermissions({
isPrivileged: true,
manifest: {
permissions: ["mozillaAddons", "mozillaAddons", "mozillaAddons", "resource://*/*", "http://a/"],
permissions: ["mozillaAddons", "mozillaAddons", "mozillaAddons", "resource://x/*", "http://a/", "about:reader*"],
},
});
deepEqual(manifestPermissions, {
origins: ["resource://*/*", "http://a/"],
origins: ["resource://x/*", "http://a/", "about:reader*"],
permissions: ["mozillaAddons"],
}, "Expected origins and permissions for privileged add-on with mozillaAddons");
@ -219,7 +219,7 @@ add_task(async function privileged_with_mozillaAddons() {
add_task(async function unprivileged_with_mozillaAddons() {
let manifestPermissions = await getManifestPermissions({
manifest: {
permissions: ["mozillaAddons", "mozillaAddons", "mozillaAddons", "resource://*/*", "http://a/"],
permissions: ["mozillaAddons", "mozillaAddons", "mozillaAddons", "resource://x/*", "http://a/", "about:reader*"],
},
});
deepEqual(manifestPermissions, {
@ -291,3 +291,38 @@ add_task(async function update_change_permissions() {
bundle.formatStringFromName("webextPerms.description.proxy", [DUMMY_APP_NAME], 1),
], "Expected permission warnings for new permissions only");
});
// Tests that a privileged extension with the mozillaAddons permission can be
// updated without errors.
add_task(async function update_privileged_with_mozillaAddons() {
let warnings = await getPermissionWarningsForUpdate({
isPrivileged: true,
manifest: {
permissions: ["mozillaAddons", "resource://a/"],
},
}, {
isPrivileged: true,
manifest: {
permissions: ["mozillaAddons", "resource://a/", "resource://b/"],
},
});
deepEqual(warnings, [
bundle.formatStringFromName("webextPerms.hostDescription.oneSite", ["b"], 1),
], "Expected permission warnings for new host only");
});
// Tests that an unprivileged extension cannot get privileged permissions
// through an update.
add_task(async function update_unprivileged_with_mozillaAddons() {
// Unprivileged
let warnings = await getPermissionWarningsForUpdate({
manifest: {
permissions: ["mozillaAddons", "resource://a/"],
},
}, {
manifest: {
permissions: ["mozillaAddons", "resource://a/", "resource://b/"],
},
});
deepEqual(warnings, [], "resource:-scheme is unsupported for unprivileged extensions");
});