Bug 1373293: Drop invalid permissions when normalizing manifests. r?bsilverberg draft
authorKris Maglione <maglione.k@gmail.com>
Wed, 21 Jun 2017 12:12:51 -0700
changeset 598518 6ef0662a0d23f7f883aa778ae5c5d619510298a9
parent 598517 2e9931b4b966db27de4853b4fa1f68433b609260
child 634492 e79f298110c84138efe309eaf45b9d4b74bd4aca
push id65220
push usermaglione.k@gmail.com
push dateWed, 21 Jun 2017 19:14:16 +0000
reviewersbsilverberg
bugs1373293
milestone56.0a1
Bug 1373293: Drop invalid permissions when normalizing manifests. r?bsilverberg MozReview-Commit-ID: EIGhP6rRLzW
toolkit/components/extensions/Schemas.jsm
toolkit/components/extensions/schemas/manifest.json
toolkit/components/extensions/test/xpcshell/test_ext_unknown_permissions.js
toolkit/components/extensions/test/xpcshell/xpcshell.ini
--- a/toolkit/components/extensions/Schemas.jsm
+++ b/toolkit/components/extensions/Schemas.jsm
@@ -1708,46 +1708,52 @@ class BooleanType extends Type {
 
   checkBaseType(baseType) {
     return baseType == "boolean";
   }
 }
 
 class ArrayType extends Type {
   static get EXTRA_PROPERTIES() {
-    return ["items", "minItems", "maxItems", ...super.EXTRA_PROPERTIES];
+    return ["items", "minItems", "maxItems", "onError", ...super.EXTRA_PROPERTIES];
   }
 
   static parseSchema(schema, path, extraProperties = []) {
     this.checkSchemaProperties(schema, path, extraProperties);
 
-    let items = Schemas.parseSchema(schema.items, path);
+    let items = Schemas.parseSchema(schema.items, path, ["onError"]);
 
     return new this(schema, items, schema.minItems || 0, schema.maxItems || Infinity);
   }
 
   constructor(schema, itemType, minItems, maxItems) {
     super(schema);
     this.itemType = itemType;
     this.minItems = minItems;
     this.maxItems = maxItems;
+    this.onError = schema.items.onError || null;
   }
 
   normalize(value, context) {
     let v = this.normalizeBase("array", value, context);
     if (v.error) {
       return v;
     }
     value = v.value;
 
     let result = [];
     for (let [i, element] of value.entries()) {
       element = context.withPath(String(i), () => this.itemType.normalize(element, context));
       if (element.error) {
-        return element;
+        if (this.onError == "warn") {
+          context.logError(element.error);
+        } else if (this.onError != "ignore") {
+          return element;
+        }
+        continue;
       }
       result.push(element.value);
     }
 
     if (result.length < this.minItems) {
       return context.error(`Array requires at least ${this.minItems} items; you have ${result.length}`,
                            `have at least ${this.minItems} items`);
     }
--- a/toolkit/components/extensions/schemas/manifest.json
+++ b/toolkit/components/extensions/schemas/manifest.json
@@ -163,23 +163,18 @@
             "format": "contentSecurityPolicy",
             "onError": "warn"
           },
 
           "permissions": {
             "type": "array",
             "default": [],
             "items": {
-              "choices": [
-                { "$ref": "Permission" },
-                {
-                  "type": "string",
-                  "deprecated": "Unknown permission ${value}"
-                }
-              ]
+              "$ref": "Permission",
+              "onError": "warn"
             },
             "optional": true
           },
 
           "optional_permissions": {
             "type": "array",
             "items": {
               "choices": [
new file mode 100644
--- /dev/null
+++ b/toolkit/components/extensions/test/xpcshell/test_ext_unknown_permissions.js
@@ -0,0 +1,23 @@
+"use strict";
+
+add_task(async function test_unknown_permissions() {
+  let extension = ExtensionTestUtils.loadExtension({
+    manifest: {
+      permissions: [
+        "activeTab",
+        "fooUnknownPermission",
+        "http://*/",
+        "chrome://favicon/",
+      ],
+    },
+  });
+
+  await extension.startup();
+
+  const {WebExtensionPolicy} = Cu.import("resource://gre/modules/Extension.jsm", {});
+
+  let policy = WebExtensionPolicy.getByID(extension.id);
+  Assert.deepEqual(policy.permissions, ["activeTab", "http://*/*"]);
+
+  await extension.unload();
+});
--- a/toolkit/components/extensions/test/xpcshell/xpcshell.ini
+++ b/toolkit/components/extensions/test/xpcshell/xpcshell.ini
@@ -82,16 +82,17 @@ skip-if = os == "android" # Bug 1350559
 [test_ext_storage_sync.js]
 head = head.js head_sync.js
 skip-if = os == "android"
 [test_ext_storage_sync_crypto.js]
 skip-if = os == "android"
 [test_ext_themes_supported_properties.js]
 [test_ext_topSites.js]
 skip-if = os == "android"
+[test_ext_unknown_permissions.js]
 [test_ext_legacy_extension_context.js]
 [test_ext_legacy_extension_embedding.js]
 [test_locale_converter.js]
 [test_locale_data.js]
 [test_native_messaging.js]
 skip-if = os == "android"
 [test_proxy_scripts.js]
 [include:xpcshell-content.ini]