Origin policy: update feature policy parsing to match the latest spec

This updates the parsing of the feature policy parts of the origin
policy manifest to mostly match the latest spec draft at
https://wicg.github.io/origin-policy/, in particular
https://wicg.github.io/origin-policy/#parsing. That is, it moves away
from "feature-policy": ["... FP string"] to
"features": { "policy": "... FP string" }. This changes the data model
from a list of FP strings to an optional FP string. Additionally, it
removes the failure on parsing errors, as those are no longer in the
spec.

This does not yet properly parse the FP string as a FP directive;
instead it still treats it as a header (so, commas are allowed inside).
A failing test is added for that case, which will be addressed in a
followup CL.

Bug: 751996
Change-Id: I51711ee9381ecfc705683ba0eb870e461fed434e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1965905
Commit-Queue: Domenic Denicola <domenic@chromium.org>
Reviewed-by: Kinuko Yasuda <kinuko@chromium.org>
Reviewed-by: Daniel Vogelheim <vogelheim@chromium.org>
Cr-Commit-Position: refs/heads/master@{#726494}
diff --git a/.well-known/origin-policy/policy-features b/.well-known/origin-policy/policy-features
deleted file mode 100644
index 143ff58..0000000
--- a/.well-known/origin-policy/policy-features
+++ /dev/null
@@ -1,6 +0,0 @@
-{
-  "feature-policy": [
-    "camera 'self' https://example.org",
-    "geolocation https://example.org/"
-  ]
-}
diff --git a/.well-known/origin-policy/policy-features-comma-in-policy b/.well-known/origin-policy/policy-features-comma-in-policy
new file mode 100644
index 0000000..e991c78
--- /dev/null
+++ b/.well-known/origin-policy/policy-features-comma-in-policy
@@ -0,0 +1,5 @@
+{
+  "features": {
+    "policy": "camera 'self' https://example.com/, geolocation 'self' https://example.com/"
+  }
+}
diff --git a/.well-known/origin-policy/policy-features-double-features b/.well-known/origin-policy/policy-features-double-features
new file mode 100644
index 0000000..583f1ea
--- /dev/null
+++ b/.well-known/origin-policy/policy-features-double-features
@@ -0,0 +1,8 @@
+{
+  "features": {
+    "policy": "camera 'self' https://example.com/"
+  },
+  "features": {
+    "policy": "geolocation 'self' https://example.com/"
+  }
+}
diff --git a/.well-known/origin-policy/policy-features-double-policy b/.well-known/origin-policy/policy-features-double-policy
new file mode 100644
index 0000000..fb216bc
--- /dev/null
+++ b/.well-known/origin-policy/policy-features-double-policy
@@ -0,0 +1,6 @@
+{
+  "features": {
+    "policy": "camera 'self' https://example.com/",
+    "policy": "geolocation 'self' https://example.com/"
+  }
+}
diff --git a/.well-known/origin-policy/policy-features-non-object b/.well-known/origin-policy/policy-features-non-object
new file mode 100644
index 0000000..b4d2554
--- /dev/null
+++ b/.well-known/origin-policy/policy-features-non-object
@@ -0,0 +1,3 @@
+{
+  "features": "camera 'self' https://example.com/"
+}
diff --git a/.well-known/origin-policy/policy-features-non-string b/.well-known/origin-policy/policy-features-non-string
new file mode 100644
index 0000000..8b758c7
--- /dev/null
+++ b/.well-known/origin-policy/policy-features-non-string
@@ -0,0 +1,5 @@
+{
+  "features": {
+    "policy": ["camera 'self' https://example.com/"]
+  }
+}
diff --git a/.well-known/origin-policy/policy-features-valid b/.well-known/origin-policy/policy-features-valid
new file mode 100644
index 0000000..22ef899
--- /dev/null
+++ b/.well-known/origin-policy/policy-features-valid
@@ -0,0 +1,5 @@
+{
+  "features": {
+    "policy": "camera 'self' https://example.com/; geolocation 'self' https://example.com/"
+  }
+}
diff --git a/origin-policy/features/comma-in-policy.https.html b/origin-policy/features/comma-in-policy.https.html
new file mode 100644
index 0000000..1b991f0
--- /dev/null
+++ b/origin-policy/features/comma-in-policy.https.html
@@ -0,0 +1,11 @@
+<!DOCTYPE HTML>
+<meta charset="utf-8">
+<title>Commas in "features/policy" cause parse errors and thus no feature policy</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="helper.js"></script>
+
+<script>
+"use strict";
+runFPTest({ camera: false, geolocation: false });
+</script>
diff --git a/origin-policy/features/comma-in-policy.https.html.headers b/origin-policy/features/comma-in-policy.https.html.headers
new file mode 100644
index 0000000..c0e6872
--- /dev/null
+++ b/origin-policy/features/comma-in-policy.https.html.headers
@@ -0,0 +1 @@
+Sec-Origin-Policy: policy=policy-features-comma-in-policy
diff --git a/origin-policy/features/double-features.https.html b/origin-policy/features/double-features.https.html
new file mode 100644
index 0000000..8397f84
--- /dev/null
+++ b/origin-policy/features/double-features.https.html
@@ -0,0 +1,11 @@
+<!DOCTYPE HTML>
+<meta charset="utf-8">
+<title>Of two "features" items only the second counts</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="helper.js"></script>
+
+<script>
+"use strict";
+runFPTest({ camera: false, geolocation: true });
+</script>
diff --git a/origin-policy/features/double-features.https.html.headers b/origin-policy/features/double-features.https.html.headers
new file mode 100644
index 0000000..f0a5738
--- /dev/null
+++ b/origin-policy/features/double-features.https.html.headers
@@ -0,0 +1 @@
+Sec-Origin-Policy: policy=policy-features-double-features
diff --git a/origin-policy/features/double-policy.https.html b/origin-policy/features/double-policy.https.html
new file mode 100644
index 0000000..f1d63d6
--- /dev/null
+++ b/origin-policy/features/double-policy.https.html
@@ -0,0 +1,11 @@
+<!DOCTYPE HTML>
+<meta charset="utf-8">
+<title>Of two "features/policy" items only the second counts</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="helper.js"></script>
+
+<script>
+"use strict";
+runFPTest({ camera: false, geolocation: true });
+</script>
diff --git a/origin-policy/features/double-policy.https.html.headers b/origin-policy/features/double-policy.https.html.headers
new file mode 100644
index 0000000..c142169
--- /dev/null
+++ b/origin-policy/features/double-policy.https.html.headers
@@ -0,0 +1 @@
+Sec-Origin-Policy: policy=policy-features-double-policy
diff --git a/origin-policy/features/helper.js b/origin-policy/features/helper.js
new file mode 100644
index 0000000..f9c16b5
--- /dev/null
+++ b/origin-policy/features/helper.js
@@ -0,0 +1,8 @@
+"use strict";
+
+window.runFPTest = ({ camera, geolocation }) => {
+  test(() => {
+    assert_equals(document.featurePolicy.allowsFeature('camera', 'https://example.com/'), camera, 'camera');
+    assert_equals(document.featurePolicy.allowsFeature('geolocation', 'https://example.com/'), geolocation, 'geolocation');
+  });
+};
diff --git a/origin-policy/features/non-object.https.html b/origin-policy/features/non-object.https.html
new file mode 100644
index 0000000..31f632b
--- /dev/null
+++ b/origin-policy/features/non-object.https.html
@@ -0,0 +1,11 @@
+<!DOCTYPE HTML>
+<meta charset="utf-8">
+<title>Non-object "features" member must be ignored</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="helper.js"></script>
+
+<script>
+"use strict";
+runFPTest({ camera: false, geolocation: false });
+</script>
diff --git a/origin-policy/features/non-object.https.html.headers b/origin-policy/features/non-object.https.html.headers
new file mode 100644
index 0000000..e8f6871
--- /dev/null
+++ b/origin-policy/features/non-object.https.html.headers
@@ -0,0 +1 @@
+Sec-Origin-Policy: policy=policy-features-non-object
diff --git a/origin-policy/features/non-string.https.html b/origin-policy/features/non-string.https.html
new file mode 100644
index 0000000..019014c
--- /dev/null
+++ b/origin-policy/features/non-string.https.html
@@ -0,0 +1,11 @@
+<!DOCTYPE HTML>
+<meta charset="utf-8">
+<title>Non-string "features/policy" member must be ignored</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="helper.js"></script>
+
+<script>
+"use strict";
+runFPTest({ camera: false, geolocation: false });
+</script>
diff --git a/origin-policy/features/non-string.https.html.headers b/origin-policy/features/non-string.https.html.headers
new file mode 100644
index 0000000..4c6c376
--- /dev/null
+++ b/origin-policy/features/non-string.https.html.headers
@@ -0,0 +1 @@
+Sec-Origin-Policy: policy=policy-features-non-string
diff --git a/origin-policy/features/valid.https.html b/origin-policy/features/valid.https.html
new file mode 100644
index 0000000..6ff2076
--- /dev/null
+++ b/origin-policy/features/valid.https.html
@@ -0,0 +1,11 @@
+<!DOCTYPE HTML>
+<meta charset="utf-8">
+<title>Valid "features" member</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="helper.js"></script>
+
+<script>
+"use strict";
+runFPTest({ camera: true, geolocation: true });
+</script>
diff --git a/origin-policy/features/valid.https.html.headers b/origin-policy/features/valid.https.html.headers
new file mode 100644
index 0000000..9d0e257
--- /dev/null
+++ b/origin-policy/features/valid.https.html.headers
@@ -0,0 +1 @@
+Sec-Origin-Policy: policy=policy-features-valid
diff --git a/origin-policy/origin-policy-features.https.tentative.html b/origin-policy/origin-policy-features.https.tentative.html
deleted file mode 100644
index e83acf1..0000000
--- a/origin-policy/origin-policy-features.https.tentative.html
+++ /dev/null
@@ -1,16 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
-  <script src='/resources/testharness.js'></script>
-  <script src='/resources/testharnessreport.js'></script>
-</head>
-<body>
-  <script>
-    async_test(t => {
-      assert_false(document.featurePolicy.allowsFeature('geolocation'));
-      assert_true(document.featurePolicy.allowsFeature('camera'));
-      t.done();
-    }, "Origin-Policy-based Feature policy");
-  </script>
-</body>
-</html>
diff --git a/origin-policy/origin-policy-features.https.tentative.html.headers b/origin-policy/origin-policy-features.https.tentative.html.headers
deleted file mode 100644
index 9864518..0000000
--- a/origin-policy/origin-policy-features.https.tentative.html.headers
+++ /dev/null
@@ -1 +0,0 @@
-Sec-Origin-Policy: policy=policy-features