Bug 1433271 - Don't fail policy validation if an array inside a object is missing. r=Mossop draft
authorFelipe Gomes <felipc@gmail.com>
Tue, 06 Feb 2018 23:17:58 -0200
changeset 751881 ee253179d40900365dd7210ecc274ceb7259f237
parent 751378 05b29220fc4de84e676cf4bfe7a673ae640dd929
child 751924 22b57b0611dee660c05de8ab88fa0d44b11d017a
child 752168 af9d41fe366c8f861d82838fa664c9d75e54e333
push id98083
push userfelipc@gmail.com
push dateWed, 07 Feb 2018 01:18:22 +0000
reviewersMossop
bugs1433271
milestone60.0a1
Bug 1433271 - Don't fail policy validation if an array inside a object is missing. r=Mossop A top-level array (i.e., if a policy directly requires an array) won't be affected by this problem, because if the array is missing, that means that that policy is not present, so it will be ignored. However, this can affect an array that is expected inside another object, for more complex policy types (like the popups permission which accepts both an 'allow' and a 'block' array of URLs. In the future, we should implement the 'required' property as defined by the JSON-Schema standard, but there's not a strong use case for it yet, so let's do the simple solution for now MozReview-Commit-ID: 4MQByYs4wzN
browser/components/enterprisepolicies/PoliciesValidator.jsm
browser/components/enterprisepolicies/tests/browser/browser_policies_validate_and_parse_API.js
--- a/browser/components/enterprisepolicies/PoliciesValidator.jsm
+++ b/browser/components/enterprisepolicies/PoliciesValidator.jsm
@@ -47,16 +47,24 @@ function validateAndParseParamRecursive(
     case "number":
     case "integer":
     case "string":
     case "URL":
     case "origin":
       return validateAndParseSimpleParam(param, properties.type);
 
     case "array":
+      if (param === undefined) {
+        // Accept a missing array as valid. Policies that use
+        // arrays should still check before iterating through
+        // the array, unless it is marked as "required" in the
+        // schema (but "required" is not implemented yet).
+        return [true, undefined];
+      }
+
       if (!Array.isArray(param)) {
         log.error("Array expected but not received");
         return [false, null];
       }
 
       let parsedArray = [];
       for (let item of param) {
         log.debug(`in array, checking @${item}@ for type ${properties.items.type}`);
--- a/browser/components/enterprisepolicies/tests/browser/browser_policies_validate_and_parse_API.js
+++ b/browser/components/enterprisepolicies/tests/browser/browser_policies_validate_and_parse_API.js
@@ -223,8 +223,39 @@ add_task(async function test_array_of_ob
   ok(typeof(parsed[0]) == "object" && typeof(parsed[1]) == "object", "Correct objects inside array");
 
   is(parsed[0].url.spec, "https://www.example.com/bookmark1", "Correct URL for bookmark 1");
   is(parsed[1].url.spec, "https://www.example.com/bookmark2", "Correct URL for bookmark 2");
 
   is(parsed[0].title, "Foo", "Correct title for bookmark 1");
   is(parsed[1].title, "Bar", "Correct title for bookmark 2");
 });
+
+add_task(async function test_missing_arrays_inside_objects() {
+  let schema = {
+    type: "object",
+    properties: {
+      allow: {
+        type: "array",
+        items: {
+          type: "boolean"
+        }
+      },
+      block: {
+        type: "array",
+        items: {
+          type: "boolean"
+        }
+      }
+
+    }
+  };
+
+  let valid, parsed;
+  [valid, parsed] = PoliciesValidator.validateAndParseParameters({
+    allow: [true, true, true]
+  }, schema);
+
+  ok(valid, "Object is valid");
+  is(parsed.allow.length, 3, "Allow array is correct.");
+  is(parsed.block, undefined, "Block array is undefined, as expected.");
+});
+