mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 05:41:12 +00:00
Bug 1197420 Part 3 Initial browser.permissions api support r=kmag
With this patch, permissions are not actually applied, but the permissions api is in place. MozReview-Commit-ID: CTaXz5sa1xy --HG-- extra : rebase_source : f623b4c7c66888ab1fb4876a3d63ec47677711b8 extra : source : e4c13d11e401ae3bd40be3a5a7fb0aaf95c992bb
This commit is contained in:
parent
70f7a8449c
commit
1b3c71a54f
@ -84,6 +84,17 @@ webextPerms.updateText=%S has been updated. You must approve new permissions bef
|
||||
webextPerms.updateAccept.label=Update
|
||||
webextPerms.updateAccept.accessKey=U
|
||||
|
||||
# LOCALIZATION NOTE (webextPerms.optionalPermsHheader)
|
||||
# %S is replace with the localized name of the extension requested new
|
||||
# permissions.
|
||||
# Note, this string will be used as raw markup. Avoid characters like <, >, &
|
||||
webextPerms.optionalPermsHeader=%S requests additional permissions.
|
||||
webextPerms.optionalPermsListIntro=It wants to:
|
||||
webextPerms.optionalPermsAllow.label=Allow
|
||||
webextPerms.optionalPermsAllow.accessKey=A
|
||||
webextPerms.optionalPermsDeny.label=Deny
|
||||
webextPerms.optionalPermsDeny.accessKey=D
|
||||
|
||||
webextPerms.description.bookmarks=Read and modify bookmarks
|
||||
webextPerms.description.clipboardRead=Get data from the clipboard
|
||||
webextPerms.description.clipboardWrite=Input data to the clipboard
|
||||
|
@ -41,6 +41,7 @@ this.ExtensionsUI = {
|
||||
Services.obs.addObserver(this, "webextension-permission-prompt", false);
|
||||
Services.obs.addObserver(this, "webextension-update-permissions", false);
|
||||
Services.obs.addObserver(this, "webextension-install-notify", false);
|
||||
Services.obs.addObserver(this, "webextension-optional-permission-prompt", false);
|
||||
|
||||
this._checkForSideloaded();
|
||||
},
|
||||
@ -203,6 +204,14 @@ this.ExtensionsUI = {
|
||||
callback();
|
||||
}
|
||||
});
|
||||
} else if (topic == "webextension-optional-permission-prompt") {
|
||||
let {browser, name, icon, permissions, resolve} = subject.wrappedJSObject;
|
||||
let strings = this._buildStrings({
|
||||
type: "optional",
|
||||
addon: {name},
|
||||
permissions,
|
||||
});
|
||||
resolve(this.showPermissionsPrompt(browser, strings, icon));
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -81,6 +81,7 @@ var {
|
||||
} = ExtensionParent;
|
||||
|
||||
const {
|
||||
classifyPermission,
|
||||
EventEmitter,
|
||||
LocaleData,
|
||||
StartupCache,
|
||||
@ -482,12 +483,11 @@ this.ExtensionData = class {
|
||||
}
|
||||
|
||||
this.permissions.add(perm);
|
||||
|
||||
let match = /^(\w+)(?:\.(\w+)(?:\.\w+)*)?$/.exec(perm);
|
||||
if (!match) {
|
||||
let type = classifyPermission(perm);
|
||||
if (type.origin) {
|
||||
whitelist.push(perm);
|
||||
} else if (match[1] == "experiments" && match[2]) {
|
||||
this.apiNames.add(match[2]);
|
||||
} else if (type.api) {
|
||||
this.apiNames.add(type.api);
|
||||
}
|
||||
}
|
||||
this.whiteListedHosts = new MatchPattern(whitelist);
|
||||
@ -680,6 +680,7 @@ this.Extension = class extends ExtensionData {
|
||||
|
||||
this.apis = [];
|
||||
this.whiteListedHosts = null;
|
||||
this._optionalOrigins = null;
|
||||
this.webAccessibleResources = null;
|
||||
|
||||
this.emitter = new EventEmitter();
|
||||
@ -1018,4 +1019,12 @@ this.Extension = class extends ExtensionData {
|
||||
get name() {
|
||||
return this.manifest.name;
|
||||
}
|
||||
|
||||
get optionalOrigins() {
|
||||
if (this._optionalOrigins == null) {
|
||||
let origins = this.manifest.optional_permissions.filter(perm => classifyPermission(perm).origin);
|
||||
this._optionalOrigins = new MatchPattern(origins);
|
||||
}
|
||||
return this._optionalOrigins;
|
||||
}
|
||||
};
|
||||
|
111
toolkit/components/extensions/ExtensionPermissions.jsm
Normal file
111
toolkit/components/extensions/ExtensionPermissions.jsm
Normal file
@ -0,0 +1,111 @@
|
||||
"use strict";
|
||||
|
||||
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
|
||||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "JSONFile",
|
||||
"resource://gre/modules/JSONFile.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "OS",
|
||||
"resource://gre/modules/osfile.jsm");
|
||||
|
||||
this.EXPORTED_SYMBOLS = ["ExtensionPermissions"];
|
||||
|
||||
const FILE_NAME = "extension-preferences.json";
|
||||
|
||||
let prefs;
|
||||
let _initPromise;
|
||||
function lazyInit() {
|
||||
if (!_initPromise) {
|
||||
prefs = new JSONFile({path: OS.Path.join(OS.Constants.Path.profileDir, FILE_NAME)});
|
||||
|
||||
_initPromise = prefs.load();
|
||||
}
|
||||
return _initPromise;
|
||||
}
|
||||
|
||||
function emptyPermissions() {
|
||||
return {permissions: [], origins: []};
|
||||
}
|
||||
|
||||
this.ExtensionPermissions = {
|
||||
async get(extension) {
|
||||
await lazyInit();
|
||||
|
||||
let perms = emptyPermissions();
|
||||
if (prefs.data[extension.id]) {
|
||||
Object.assign(perms, prefs.data[extension.id]);
|
||||
}
|
||||
return perms;
|
||||
},
|
||||
|
||||
// Add new permissions for the given extension. `permissions` is
|
||||
// in the format that is passed to browser.permissions.request().
|
||||
async add(extension, perms) {
|
||||
await lazyInit();
|
||||
|
||||
if (!prefs.data[extension.id]) {
|
||||
prefs.data[extension.id] = emptyPermissions();
|
||||
}
|
||||
let {permissions, origins} = prefs.data[extension.id];
|
||||
|
||||
let added = emptyPermissions();
|
||||
|
||||
for (let perm of perms.permissions) {
|
||||
if (!permissions.includes(perm)) {
|
||||
added.permissions.push(perm);
|
||||
permissions.push(perm);
|
||||
}
|
||||
}
|
||||
for (let origin of perms.origins) {
|
||||
if (!origins.includes(origin)) {
|
||||
added.origins.push(origin);
|
||||
origins.push(origin);
|
||||
}
|
||||
}
|
||||
|
||||
if (added.permissions.length > 0 || added.origins.length > 0) {
|
||||
prefs.saveSoon();
|
||||
// TODO apply the changes
|
||||
}
|
||||
},
|
||||
|
||||
// Revoke permissions from the given extension. `permissions` is
|
||||
// in the format that is passed to browser.permissions.remove().
|
||||
async remove(extension, perms) {
|
||||
await lazyInit();
|
||||
|
||||
if (!prefs.data[extension.id]) {
|
||||
return;
|
||||
}
|
||||
let {permissions, origins} = prefs.data[extension.id];
|
||||
|
||||
let removed = emptyPermissions();
|
||||
|
||||
for (let perm of perms.permissions) {
|
||||
let i = permissions.indexOf(perm);
|
||||
if (i >= 0) {
|
||||
removed.permissions.push(perm);
|
||||
permissions.splice(i, 1);
|
||||
}
|
||||
}
|
||||
for (let origin of perms.origins) {
|
||||
let i = origins.indexOf(origin);
|
||||
if (i >= 0) {
|
||||
removed.origins.push(origin);
|
||||
origins.splice(i, 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (removed.permissions.length > 0 || removed.origins.length > 0) {
|
||||
prefs.saveSoon();
|
||||
// TODO apply the changes
|
||||
}
|
||||
},
|
||||
|
||||
async removeAll(extension) {
|
||||
await lazyInit();
|
||||
delete prefs.data[extension.id];
|
||||
prefs.saveSoon();
|
||||
},
|
||||
};
|
@ -1328,7 +1328,31 @@ class MessageManagerProxy {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Classify an individual permission from a webextension manifest
|
||||
* as a host/origin permission, an api permission, or a regular permission.
|
||||
*
|
||||
* @param {string} perm The permission string to classify
|
||||
*
|
||||
* @returns {object}
|
||||
* An object with exactly one of the following properties:
|
||||
* "origin" to indicate this is a host/origin permission.
|
||||
* "api" to indicate this is an api permission
|
||||
* (as used for webextensions experiments).
|
||||
* "permission" to indicate this is a regular permission.
|
||||
*/
|
||||
function classifyPermission(perm) {
|
||||
let match = /^(\w+)(?:\.(\w+)(?:\.\w+)*)?$/.exec(perm);
|
||||
if (!match) {
|
||||
return {origin: perm};
|
||||
} else if (match[1] == "experiments" && match[2]) {
|
||||
return {api: match[2]};
|
||||
}
|
||||
return {permission: perm};
|
||||
}
|
||||
|
||||
this.ExtensionUtils = {
|
||||
classifyPermission,
|
||||
defineLazyGetter,
|
||||
detectLanguage,
|
||||
extend,
|
||||
|
19
toolkit/components/extensions/ext-c-permissions.js
Normal file
19
toolkit/components/extensions/ext-c-permissions.js
Normal file
@ -0,0 +1,19 @@
|
||||
"use strict";
|
||||
|
||||
Cu.import("resource://gre/modules/ExtensionUtils.jsm");
|
||||
const {ExtensionError} = ExtensionUtils;
|
||||
|
||||
extensions.registerSchemaAPI("permissions", "addon_child", context => {
|
||||
return {
|
||||
permissions: {
|
||||
async request(perms) {
|
||||
let winUtils = context.contentWindow.getInterface(Ci.nsIDOMWindowUtils);
|
||||
if (!winUtils.isHandlingUserInput) {
|
||||
throw new ExtensionError("May only request permissions from a user input handler");
|
||||
}
|
||||
|
||||
return context.childManager.callParentAsyncFunction("permissions.request_parent", [perms]);
|
||||
},
|
||||
},
|
||||
};
|
||||
});
|
97
toolkit/components/extensions/ext-permissions.js
Normal file
97
toolkit/components/extensions/ext-permissions.js
Normal file
@ -0,0 +1,97 @@
|
||||
"use strict";
|
||||
|
||||
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
|
||||
|
||||
Cu.import("resource://gre/modules/ExtensionUtils.jsm");
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "ExtensionPermissions",
|
||||
"resource://gre/modules/ExtensionPermissions.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
|
||||
"resource://gre/modules/NetUtil.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Services",
|
||||
"resource://gre/modules/Services.jsm");
|
||||
|
||||
const {
|
||||
ExtensionError,
|
||||
} = ExtensionUtils;
|
||||
|
||||
XPCOMUtils.defineLazyPreferenceGetter(this, "promptsEnabled",
|
||||
"extensions.webextOptionalPermissionPrompts");
|
||||
|
||||
extensions.registerSchemaAPI("permission", "addon_parent", context => {
|
||||
return {
|
||||
permissions: {
|
||||
async request_parent(perms) {
|
||||
let {permissions, origins} = perms;
|
||||
|
||||
let manifestPermissions = context.extension.manifest.optional_permissions;
|
||||
for (let perm of permissions) {
|
||||
if (!manifestPermissions.includes(perm)) {
|
||||
throw new ExtensionError(`Cannot request permission ${perm} since it was not declared in optional_permissions`);
|
||||
}
|
||||
}
|
||||
|
||||
let optionalOrigins = context.extension.optionalOrigins;
|
||||
for (let origin of origins) {
|
||||
if (!optionalOrigins.subsumes(origin)) {
|
||||
throw new ExtensionError(`Cannot request origin permission for ${origin} since it was not declared in optional_permissions`);
|
||||
}
|
||||
}
|
||||
|
||||
if (promptsEnabled) {
|
||||
let allow = await new Promise(resolve => {
|
||||
let subject = {
|
||||
wrappedJSObject: {
|
||||
browser: context.xulBrowser,
|
||||
name: context.extension.name,
|
||||
icon: context.extension.iconURL,
|
||||
permissions: {permissions, origins},
|
||||
resolve,
|
||||
},
|
||||
};
|
||||
Services.obs.notifyObservers(subject, "webextension-optional-permission-prompt", null);
|
||||
});
|
||||
if (!allow) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
await ExtensionPermissions.add(context.extension, perms);
|
||||
return true;
|
||||
},
|
||||
|
||||
async getAll() {
|
||||
let perms = context.extension.userPermissions;
|
||||
delete perms.apis;
|
||||
return perms;
|
||||
},
|
||||
|
||||
async contains(permissions) {
|
||||
for (let perm of permissions.permissions) {
|
||||
if (!context.extension.hasPermission(perm)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
for (let origin of permissions.origins) {
|
||||
if (!context.extension.whiteListedHosts.subsumes(origin)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
async remove(permissions) {
|
||||
await ExtensionPermissions.remove(context.extension, permissions);
|
||||
return true;
|
||||
},
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
/* eslint-disable mozilla/balanced-listeners */
|
||||
extensions.on("uninstall", extension => {
|
||||
ExtensionPermissions.removeAll(extension);
|
||||
});
|
@ -11,6 +11,7 @@ category webextension-scripts i18n chrome://extensions/content/ext-i18n.js
|
||||
category webextension-scripts idle chrome://extensions/content/ext-idle.js
|
||||
category webextension-scripts management chrome://extensions/content/ext-management.js
|
||||
category webextension-scripts notifications chrome://extensions/content/ext-notifications.js
|
||||
category webextension-scripts permissions chrome://extensions/content/ext-permissions.js
|
||||
category webextension-scripts privacy chrome://extensions/content/ext-privacy.js
|
||||
category webextension-scripts proxy chrome://extensions/content/ext-proxy.js
|
||||
category webextension-scripts runtime chrome://extensions/content/ext-runtime.js
|
||||
@ -23,6 +24,7 @@ category webextension-scripts webRequest chrome://extensions/content/ext-webRequ
|
||||
# scripts specific for content process.
|
||||
category webextension-scripts-content extension chrome://extensions/content/ext-c-extension.js
|
||||
category webextension-scripts-content i18n chrome://extensions/content/ext-i18n.js
|
||||
category webextension-scripts-content permissions chrome://extensions/content/ext-c-permissions.js
|
||||
category webextension-scripts-content runtime chrome://extensions/content/ext-c-runtime.js
|
||||
category webextension-scripts-content storage chrome://extensions/content/ext-c-storage.js
|
||||
category webextension-scripts-content test chrome://extensions/content/ext-c-test.js
|
||||
@ -41,6 +43,7 @@ category webextension-scripts-addon i18n chrome://extensions/content/ext-i18n.js
|
||||
#ifndef ANDROID
|
||||
category webextension-scripts-addon identity chrome://extensions/content/ext-c-identity.js
|
||||
#endif
|
||||
category webextension-scripts-addon permissions chrome://extensions/content/ext-c-permissions.js
|
||||
category webextension-scripts-addon runtime chrome://extensions/content/ext-c-runtime.js
|
||||
category webextension-scripts-addon storage chrome://extensions/content/ext-c-storage.js
|
||||
category webextension-scripts-addon test chrome://extensions/content/ext-c-test.js
|
||||
@ -62,6 +65,7 @@ category webextension-schemas idle chrome://extensions/content/schemas/idle.json
|
||||
category webextension-schemas management chrome://extensions/content/schemas/management.json
|
||||
category webextension-schemas native_host_manifest chrome://extensions/content/schemas/native_host_manifest.json
|
||||
category webextension-schemas notifications chrome://extensions/content/schemas/notifications.json
|
||||
category webextension-schemas permissions chrome://extensions/content/schemas/permissions.json
|
||||
category webextension-schemas privacy chrome://extensions/content/schemas/privacy.json
|
||||
category webextension-schemas proxy chrome://extensions/content/schemas/proxy.json
|
||||
category webextension-schemas runtime chrome://extensions/content/schemas/runtime.json
|
||||
|
@ -16,6 +16,7 @@ toolkit.jar:
|
||||
content/extensions/ext-idle.js
|
||||
content/extensions/ext-management.js
|
||||
content/extensions/ext-notifications.js
|
||||
content/extensions/ext-permissions.js
|
||||
content/extensions/ext-privacy.js
|
||||
content/extensions/ext-protocolHandlers.js
|
||||
content/extensions/ext-proxy.js
|
||||
@ -32,6 +33,7 @@ toolkit.jar:
|
||||
#ifndef ANDROID
|
||||
content/extensions/ext-c-identity.js
|
||||
#endif
|
||||
content/extensions/ext-c-permissions.js
|
||||
content/extensions/ext-c-runtime.js
|
||||
content/extensions/ext-c-storage.js
|
||||
content/extensions/ext-c-test.js
|
||||
|
@ -12,6 +12,7 @@ EXTRA_JS_MODULES += [
|
||||
'ExtensionContent.jsm',
|
||||
'ExtensionManagement.jsm',
|
||||
'ExtensionParent.jsm',
|
||||
'ExtensionPermissions.jsm',
|
||||
'ExtensionPreferencesManager.jsm',
|
||||
'ExtensionSettingsStore.jsm',
|
||||
'ExtensionStorage.jsm',
|
||||
|
@ -22,6 +22,7 @@ toolkit.jar:
|
||||
content/extensions/schemas/manifest.json
|
||||
content/extensions/schemas/native_host_manifest.json
|
||||
content/extensions/schemas/notifications.json
|
||||
content/extensions/schemas/permissions.json
|
||||
content/extensions/schemas/proxy.json
|
||||
content/extensions/schemas/privacy.json
|
||||
content/extensions/schemas/runtime.json
|
||||
|
153
toolkit/components/extensions/schemas/permissions.json
Normal file
153
toolkit/components/extensions/schemas/permissions.json
Normal file
@ -0,0 +1,153 @@
|
||||
[
|
||||
{
|
||||
"namespace": "permissions",
|
||||
"permissions": ["manifest:optional_permissions"],
|
||||
"types": [
|
||||
{
|
||||
"id": "Permissions",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"permissions": {
|
||||
"type": "array",
|
||||
"items": { "$ref": "manifest.OptionalPermission" },
|
||||
"optional": true,
|
||||
"default": []
|
||||
},
|
||||
"origins": {
|
||||
"type": "array",
|
||||
"items": { "$ref": "manifest.MatchPattern" },
|
||||
"optional": true,
|
||||
"default": []
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "AnyPermissions",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"permissions": {
|
||||
"type": "array",
|
||||
"items": { "$ref": "manifest.Permission" },
|
||||
"optional": true,
|
||||
"default": []
|
||||
},
|
||||
"origins": {
|
||||
"type": "array",
|
||||
"items": { "$ref": "manifest.MatchPattern" },
|
||||
"optional": true,
|
||||
"default": []
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"functions": [
|
||||
{
|
||||
"name": "getAll",
|
||||
"type": "function",
|
||||
"async": "callback",
|
||||
"description": "Get a list of all the extension's permissions.",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "callback",
|
||||
"type": "function",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "permissions",
|
||||
"$ref": "AnyPermissions"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "contains",
|
||||
"type": "function",
|
||||
"async": "callback",
|
||||
"description": "Check if the extension has the given permissions.",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "permissions",
|
||||
"$ref": "AnyPermissions"
|
||||
},
|
||||
{
|
||||
"name": "callback",
|
||||
"type": "function",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "result",
|
||||
"type": "boolean"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "request",
|
||||
"type": "function",
|
||||
"allowedContexts": ["content"],
|
||||
"async": "callback",
|
||||
"description": "Request the given permissions.",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "permissions",
|
||||
"$ref": "Permissions"
|
||||
},
|
||||
{
|
||||
"name": "callback",
|
||||
"type": "function",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "granted",
|
||||
"type": "boolean"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "remove",
|
||||
"type": "function",
|
||||
"async": "callback",
|
||||
"description": "Relinquish the given permissions.",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "permissions",
|
||||
"$ref": "Permissions"
|
||||
},
|
||||
{
|
||||
"name": "callback",
|
||||
"type": "function",
|
||||
"parameters": [
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"events": [
|
||||
{
|
||||
"name": "onAdded",
|
||||
"type": "function",
|
||||
"unsupported": true,
|
||||
"description": "Fired when the extension acquires new permissions.",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "permissions",
|
||||
"$ref": "Permissions"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "onRemoved",
|
||||
"type": "function",
|
||||
"unsupported": true,
|
||||
"description": "Fired when permissions are removed from the extension.",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "permissions",
|
||||
"$ref": "Permissions"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
@ -21,6 +21,12 @@ this.EXPORTED_SYMBOLS = ["MatchPattern", "MatchGlobs", "MatchURLFilters"];
|
||||
const PERMITTED_SCHEMES = ["http", "https", "file", "ftp", "data"];
|
||||
const PERMITTED_SCHEMES_REGEXP = PERMITTED_SCHEMES.join("|");
|
||||
|
||||
// The basic RE for matching patterns
|
||||
const PATTERN_REGEXP = new RegExp(`^(${PERMITTED_SCHEMES_REGEXP}|\\*)://(\\*|\\*\\.[^*/]+|[^*/]+|)(/.*)$`);
|
||||
|
||||
// The schemes/protocols implied by a pattern that starts with *://
|
||||
const WILDCARD_SCHEMES = ["http", "https"];
|
||||
|
||||
// This function converts a glob pattern (containing * and possibly ?
|
||||
// as wildcards) to a regular expression.
|
||||
function globToRegexp(pat, allowQuestion) {
|
||||
@ -47,8 +53,7 @@ function SingleMatchPattern(pat) {
|
||||
} else if (!pat) {
|
||||
this.schemes = [];
|
||||
} else {
|
||||
let re = new RegExp(`^(${PERMITTED_SCHEMES_REGEXP}|\\*)://(\\*|\\*\\.[^*/]+|[^*/]+|)(/.*)$`);
|
||||
let match = re.exec(pat);
|
||||
let match = PATTERN_REGEXP.exec(pat);
|
||||
if (!match) {
|
||||
Cu.reportError(`Invalid match pattern: '${pat}'`);
|
||||
this.schemes = [];
|
||||
@ -56,7 +61,7 @@ function SingleMatchPattern(pat) {
|
||||
}
|
||||
|
||||
if (match[1] == "*") {
|
||||
this.schemes = ["http", "https"];
|
||||
this.schemes = WILDCARD_SCHEMES;
|
||||
} else {
|
||||
this.schemes = [match[1]];
|
||||
}
|
||||
@ -174,6 +179,23 @@ MatchPattern.prototype = {
|
||||
return false;
|
||||
},
|
||||
|
||||
// Test if this MatchPattern subsumes the given pattern (i.e., whether
|
||||
// this pattern matches everything the given pattern does).
|
||||
// Note, this method considers only to protocols and hosts/domains,
|
||||
// paths are ignored.
|
||||
subsumes(pattern) {
|
||||
let match = PATTERN_REGEXP.exec(pattern);
|
||||
if (!match) {
|
||||
throw new Error("Invalid match pattern");
|
||||
}
|
||||
|
||||
if (match[1] == "*") {
|
||||
return WILDCARD_SCHEMES.every(scheme => this.matchesIgnoringPath({scheme, host: match[2]}));
|
||||
}
|
||||
|
||||
return this.matchesIgnoringPath({scheme: match[1], host: match[2]});
|
||||
},
|
||||
|
||||
serialize() {
|
||||
return this.pat;
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user