Skip to content

Commit 4b040f3

Browse files
WebMCP: Reject invalid origins with "NotSupportedError"
See https://crrev.com/c/8121241/comment/a263bec5_46b078a4/ and webmachinelearning/webmcp#226 (comment). With both Mason *and* François, we should migrate from DataError => NotSupportedError. R=masonf Bug: 489045948,536063275 Change-Id: I9e5fc78b082de179c016f8a16dc052744ee28513
1 parent f4b24b4 commit 4b040f3

2 files changed

Lines changed: 49 additions & 9 deletions

File tree

webmcp/declarative/opaque-origin-tools.https.html

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@
2525

2626
await promise_rejects_dom(
2727
t,
28-
'DataError',
28+
'NotSupportedError',
2929
document.modelContext.executeTool(tool, '{"param1":"value"}'),
30-
'executeTool() must reject with DataError in opaque origin documents'
30+
'executeTool() must reject with NotSupportedError in opaque origin documents'
3131
);
3232
}, 'An opaque origin document can register but not execute its own declarative tools');
3333

@@ -48,9 +48,9 @@
4848

4949
await promise_rejects_dom(
5050
t,
51-
'DataError',
51+
'NotSupportedError',
5252
document.modelContext.executeTool(tool, '{"param1":"value"}'),
53-
'executeTool() must reject with DataError in opaque origin documents'
53+
'executeTool() must reject with NotSupportedError in opaque origin documents'
5454
);
5555

5656
assert_array_equals(events, ['rejection', 'microtask'],

webmcp/imperative/opaque-origin-tools.https.html

Lines changed: 45 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,28 @@
2525

2626
await promise_rejects_dom(
2727
t,
28-
'DataError',
28+
'NotSupportedError',
2929
document.modelContext.executeTool(tool, '{}'),
30-
'executeTool() must reject with DataError in opaque origin documents'
30+
'executeTool() must reject with NotSupportedError in opaque origin documents'
3131
);
3232
}, 'An opaque origin document can register but not execute its own tools');
3333

34+
// The below three tests are almost the same, with the following distinctions:
35+
// 1. The first test asserts that executing a tool whose origin as returned
36+
// from `getTools()` is "null", synchronously rejects the execution
37+
// Promise. "null" fails to parse as a URL, because we don't parse it
38+
// relative to the document's URL as a base URL.
39+
// 2. The second and third tests below, captured by
40+
// `invalid_execution_origins`, don't reference legitimately-registered
41+
// tools. Instead, they test when the passed-in tool origin is:
42+
//
43+
// a.) An invalid URL that's not a single "null" string value. Rather, it's
44+
// an `https://` URL that fails to parse due to an invalid port.
45+
// b.) A string that successfully parses as a URL, but whose origin is opaque.
3446
promise_test(async t => {
3547
const tools = await document.modelContext.getTools();
3648
const tool = tools.find(t => t.name === 'opaque_tool');
49+
assert_equals(tool.origin, "null", "getTools() gives");
3750

3851
let events = [];
3952
const p = document.modelContext.executeTool(tool, '{}');
@@ -48,14 +61,41 @@
4861

4962
await promise_rejects_dom(
5063
t,
51-
'DataError',
64+
'NotSupportedError',
5265
document.modelContext.executeTool(tool, '{"param1":"value"}'),
53-
'executeTool() must reject with DataError in opaque origin documents'
66+
'executeTool() must reject with NotSupportedError in opaque origin documents'
5467
);
5568

5669
assert_array_equals(events, ['rejection', 'microtask'],
5770
'returned promise is rejected before custom microtask is queued');
58-
}, 'executeTool() rejects synchronously for opaque origins');
71+
}, 'executeTool() rejects synchronously for origin "null" that fails to parse as a URL');
72+
73+
const invalid_execution_origins = ["https://test.example:invalidport", "data:text/html,foo"];
74+
for (const invalid_origin of invalid_execution_origins) {
75+
promise_test(async t => {
76+
const fake_tool = {
77+
name: 'data_opaque_tool',
78+
description: 'Data URL opaque tool description',
79+
window: window,
80+
origin: invalid_origin
81+
};
82+
83+
let events = [];
84+
const p = document.modelContext.executeTool(fake_tool, '{}');
85+
p.catch(() => events.push('rejection'));
86+
87+
// Queue another microtask immediately after.
88+
queueMicrotask(() => events.push('microtask'));
89+
90+
await promise_rejects_dom(
91+
t,
92+
'NotSupportedError',
93+
document.modelContext.executeTool(fake_tool, '{"param1":"value"}'));
94+
95+
assert_array_equals(events, ['rejection', 'microtask'],
96+
'returned promise is rejected before custom microtask is queued');
97+
}, `executeTool() rejects synchronously for invalid origin: ${invalid_origin}`);
98+
}
5999
</script>
60100
</body>
61101
</html>

0 commit comments

Comments
 (0)