Skip to content

Commit

Permalink
serial: Handle opaque top level origin in addedEventListener
Browse files Browse the repository at this point in the history
In navigator.serial.addEventListener, throw an exception if the request
is coming from a context whose top level frame has an opaque origin.

Bug: 1375133
Change-Id: Ie8ad8333b901f795f55658894551c73f755029c4
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4313307
Commit-Queue: Jack Hsieh <chengweih@chromium.org>
Reviewed-by: Reilly Grant <reillyg@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1116683}
  • Loading branch information
chengweih001 authored and chromium-wpt-export-bot committed Mar 14, 2023
1 parent f78ecc4 commit c48a739
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 15 deletions.
14 changes: 6 additions & 8 deletions serial/getPorts/sandboxed_iframe.https.window.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
'use strict';

let iframe = document.createElement('iframe');

promise_test(async () => {
promise_test(async (t) => {
let iframe = document.createElement('iframe');
await new Promise(resolve => {
iframe.src = '../resources/open-in-iframe.html';
iframe.sandbox.add('allow-scripts');
Expand All @@ -12,11 +11,10 @@ promise_test(async () => {
});

await new Promise(resolve => {
iframe.contentWindow.postMessage({type: 'GetPorts'}, '*');

window.addEventListener('message', (messageEvent) => {
assert_equals('Success', messageEvent.data);
window.addEventListener('message', t.step_func(messageEvent => {
assert_equals(messageEvent.data, 'Success');
resolve();
});
}));
iframe.contentWindow.postMessage({type: 'GetPorts'}, '*');
});
}, 'GetPorts from a sandboxed iframe is valid.');
12 changes: 5 additions & 7 deletions serial/requestPort/sandboxed_iframe.https.window.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
'use strict';

let iframe = document.createElement('iframe');

promise_test(async () => {
promise_test(async (t) => {
let iframe = document.createElement('iframe');
await new Promise(resolve => {
iframe.src = '../resources/open-in-iframe.html';
iframe.sandbox.add('allow-scripts');
Expand All @@ -12,15 +11,14 @@ promise_test(async () => {
});

await new Promise(resolve => {
iframe.contentWindow.postMessage({type: 'RequestPort'}, '*');

window.addEventListener('message', (messageEvent) => {
window.addEventListener('message', t.step_func(messageEvent => {
// The failure message of no device chosen is expected. The point here is
// to validate not failing because of a sandboxed iframe.
assert_equals(
'FAIL: NotFoundError: Failed to execute \'requestPort\' on \'Serial\': No port selected by the user.',
messageEvent.data);
resolve();
});
}));
iframe.contentWindow.postMessage({type: 'RequestPort'}, '*');
});
}, 'RequestPort from a sandboxed iframe is valid.');
26 changes: 26 additions & 0 deletions serial/serial-disabled-by-permissions-policy.https.sub.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
<body>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/test-only-api.js"></script>
<script src="/serial/resources/automation.js"></script>
<script src="/permissions-policy/resources/permissions-policy.js"></script>
<script>
'use strict';
Expand All @@ -13,6 +15,14 @@
const cross_origin_worker_frame_src = sub + same_origin_worker_frame_src;
const header = 'Permissions-Policy header serial=()';

async function sleep(timeout) {
return new Promise(resolve => {
step_timeout(() => {
resolve();
}, timeout);
});
}

promise_test(() => {
return navigator.serial.getPorts().then(() => {
assert_unreached('expected promise to reject with SecurityError');
Expand Down Expand Up @@ -44,5 +54,21 @@

fetch_tests_from_worker(new Worker(
'resources/serial-disabled-by-permissions-policy-worker.js'));

serial_test(async (t, fake) => {
let eventWatcher = new EventWatcher(t, navigator.serial, 'connect');

// This isn't necessary as the expected scenario shouldn't send any mojo
// request. However, in order to capture a bug that doesn't reject adding
// event listener, time delay here is to allow mojo request to be intercepted
// after adding connect event listener.
await sleep(100);

// If device connect event fires, EventWatcher will assert for an unexpected
// event.
fake.addPort();
// Time delay here is to allow event to be fired if any.
await sleep(100);
}, 'Connect event is not fired when serial is disallowed.');
</script>
</body>

0 comments on commit c48a739

Please sign in to comment.