Support enum-type parameterized feature policy
Note: this CL does not include the parser implementation
This allows us to specify value as following:
feature_name *(enum1) 'self'(enum2);
To specify a enum, you need to provide max value and min value,
otherwise 0 and numeric_limit<unsigned>::max() is used.
To check if a feature is enabled, instead of using the threshold
value, call feature_policy->GetFeatureValueForOrigin(feature, origin)
and interpret the enum to get the feature state.
Bug: 924568
Change-Id: I2e5ca7e82cfbd3b9258dd84fc6735e9b548099f4
diff --git a/feature-policy/parameters/feature-parameters-inf.html b/feature-policy/parameters/feature-parameters-inf.html
new file mode 100644
index 0000000..db21427
--- /dev/null
+++ b/feature-policy/parameters/feature-parameters-inf.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>Test oversized-images policy with threshold 'inf'</title>
+</head>
+<body>
+ <!-- The sample image has an intrinsic image size of 200x200px -->
+ <img src="resources/sample-1.png" width="200" height="200">
+ <img src="resources/sample-1.png" width="100" height="200">
+ <img src="resources/sample-1.png" width="50" height="200">
+ <br>
+ <img src="resources/sample-1.png" width="200" height="100">
+ <img src="resources/sample-1.png" width="100" height="100">
+ <img src="resources/sample-1.png" width="50" height="100">
+ <br>
+ <img src="resources/sample-1.png" width="200" height="50">
+ <img src="resources/sample-1.png" width="100" height="50">
+ <img src="resources/sample-1.png" width="50" height="50">
+</body>
+</html>
diff --git a/feature-policy/parameters/feature-parameters-inf.html.headers b/feature-policy/parameters/feature-parameters-inf.html.headers
new file mode 100644
index 0000000..1ec0034
--- /dev/null
+++ b/feature-policy/parameters/feature-parameters-inf.html.headers
@@ -0,0 +1 @@
+Feature-Policy: oversized-images (inf)
diff --git a/feature-policy/parameters/feature-parameters-with-frames.html b/feature-policy/parameters/feature-parameters-with-frames.html
new file mode 100644
index 0000000..de0a3ab
--- /dev/null
+++ b/feature-policy/parameters/feature-parameters-with-frames.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/feature-policy/resources/featurepolicy.js"></script>
+ <title>Test oversized-images policy with threshold 1.5</title>
+</head>
+<body>
+ <iframe scrolling="no" name="a" style="overflow:hidden" width="380" height="220"></iframe>
+ <iframe scrolling="no" name="b" style="overflow:hidden" width="380" height="220"></iframe>
+ <iframe scrolling="no" name="c" style="overflow:hidden" width="380" height="220"></iframe>
+ <iframe scrolling="no" name="d" style="overflow:hidden" width="380" height="220"></iframe>
+ <iframe scrolling="no" name="e" style="overflow:hidden" width="380" height="220"></iframe>
+
+ <script>
+ const frame_to_test_map = {};
+ window.addEventListener('message', ev => {
+ if (ev.data.type == "finished") {
+ if (frame_to_test_map.hasOwnProperty(ev.data.name)) {
+ frame_to_test_map[ev.data.name].done();
+ }
+ }
+ });
+ const config = {
+ a: {threshold: 0.0, blocked: 3},
+ b: {threshold: 1.0, blocked: 2},
+ c: {threshold: 2.5, blocked: 1},
+ d: {threshold: 4.0, blocked: 0},
+ e: {threshold: "inf", blocked: 0}
+ };
+ const iframes = document.querySelectorAll('iframe');
+ const total_iframes = iframes.length;
+ iframes.forEach(iframe => {
+ const frame_config = config[iframe.name]
+ async_test(t => {
+ frame_to_test_map[iframe.name] = t;
+ iframe.src = "resources/feature-parameters-frame.html?name="+iframe.name+"&n="+frame_config.blocked+"&pipe=header(Feature-Policy,oversized-images%20("+frame_config.threshold+"\\);)";
+ }, "Test frame with threshold " + frame_config.threshold + " should block " + frame_config.blocked + " images.");
+ });
+ </script>
+</body>
+</html>
diff --git a/feature-policy/parameters/feature-parameters.html b/feature-policy/parameters/feature-parameters.html
new file mode 100644
index 0000000..9830f93
--- /dev/null
+++ b/feature-policy/parameters/feature-parameters.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/feature-policy/resources/featurepolicy.js"></script>
+ <title>Test oversized-images policy with threshold 1.5</title>
+</head>
+<body>
+ <!-- The sample image has an intrinsic image size of 200x200px -->
+ <img src="resources/sample-1.png" width="200" height="200">
+ <img src="resources/sample-1.png" width="100" height="200">
+ <img src="resources/sample-1.png" width="50" height="200">
+ <br>
+ <img src="resources/sample-1.png" width="200" height="100">
+ <img src="resources/sample-1.png" width="100" height="100">
+ <img src="resources/sample-1.png" width="50" height="100">
+ <br>
+ <img src="resources/sample-1.png" width="200" height="50">
+ <img src="resources/sample-1.png" width="100" height="50">
+ <img src="resources/sample-1.png" width="50" height="50">
+
+ <script>
+ expect_reports(8, "oversized-images", "8 images should be blocked by policy");
+ </script>
+</body>
+</html>
diff --git a/feature-policy/parameters/feature-parameters.html.headers b/feature-policy/parameters/feature-parameters.html.headers
new file mode 100644
index 0000000..b4fa805
--- /dev/null
+++ b/feature-policy/parameters/feature-parameters.html.headers
@@ -0,0 +1 @@
+Feature-Policy: oversized-images (1.5)
diff --git a/feature-policy/parameters/resources/feature-parameters-frame.html b/feature-policy/parameters/resources/feature-parameters-frame.html
new file mode 100644
index 0000000..4f01f85
--- /dev/null
+++ b/feature-policy/parameters/resources/feature-parameters-frame.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/feature-policy/resources/featurepolicy.js"></script>
+ <title>Test oversized-images policy in subframe</title>
+</head>
+<body>
+ <!-- The sample image has an intrinsic image size of 200x200px -->
+ <img width="200" height="200">
+ <img width="100" height="200">
+ <img width="50" height="200">
+
+ <script>
+ const policy_name = "oversized-images";
+ const params = new URLSearchParams(document.location.search);
+ const frame_name = params.get('name');
+ const expected_report_count = +params.get('n');
+ var num_received_reports = 0;
+
+ const images = document.querySelectorAll('img');
+ const total_images = images.length;
+ var images_loaded = 0;
+
+ const notifyIfDone = () => {
+ if (num_received_reports >= expected_report_count &&
+ images_loaded == total_images) {
+ parent.postMessage({
+ "type": "finished",
+ "name": frame_name
+ },"*");
+ }
+ };
+
+ images.forEach(image => {
+ image.addEventListener('load', () => { images_loaded++; notifyIfDone(); });
+ image.src = "sample-1.png";
+ });
+
+ new ReportingObserver((reports, observer) => {
+ const relevant_reports = reports.filter(r => (r.body.featureId === policy_name));
+ num_received_reports += relevant_reports.length;
+ notifyIfDone();
+ }, {types: ['feature-policy-violation'], buffered: true}).observe();
+ </script>
+
+</body>
+</html>
diff --git a/feature-policy/parameters/resources/sample-1.png b/feature-policy/parameters/resources/sample-1.png
new file mode 100644
index 0000000..9290192
--- /dev/null
+++ b/feature-policy/parameters/resources/sample-1.png
Binary files differ
diff --git a/feature-policy/resources/featurepolicy.js b/feature-policy/resources/featurepolicy.js
index e2577f3..744c4c6 100644
--- a/feature-policy/resources/featurepolicy.js
+++ b/feature-policy/resources/featurepolicy.js
@@ -433,3 +433,16 @@
assert_false(frame_policy.allowedFeatures().includes(feature));
}
}
+
+function expect_reports(report_count, policy_name, description) {
+ async_test(t => {
+ var num_received_reports = 0;
+ new ReportingObserver(t.step_func((reports, observer) => {
+ const relevant_reports = reports.filter(r => (r.body.featureId === policy_name));
+ num_received_reports += relevant_reports.length;
+ if (num_received_reports >= report_count) {
+ t.done();
+ }
+ }), {types: ['feature-policy-violation'], buffered: true}).observe();
+ }, description);
+}