1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
|
// META: timeout=long
//
// Test some edge cases around navigation to data: URLs to ensure they use the same code path
[
{
input: "data:text/html,<script>parent.postMessage(1, '*')</script>",
result: 1,
name: "Nothing fancy",
},
{
input: "data:text/html;base64,PHNjcmlwdD5wYXJlbnQucG9zdE1lc3NhZ2UoMiwgJyonKTwvc2NyaXB0Pg==",
result: 2,
name: "base64",
},
{
input: "data:text/html;base64,PHNjcmlwdD5wYXJlbnQucG9zdE1lc3NhZ2UoNCwgJyonKTwvc2NyaXB0Pr+/",
result: 4,
name: "base64 with code points that differ from base64url"
},
{
input: "data:text/html;base64,PHNjcml%09%20%20%0A%0C%0DwdD5wYXJlbnQucG9zdE1lc3NhZ2UoNiwgJyonKTwvc2NyaXB0Pg==",
result: 6,
name: "ASCII whitespace in the input is removed"
}
].forEach(({ input, result, name }) => {
// Use promise_test so they go sequentially
promise_test(async t => {
const event = await new Promise((resolve, reject) => {
self.addEventListener("message", t.step_func(resolve), { once: true });
const frame = document.body.appendChild(document.createElement("iframe"));
t.add_cleanup(() => frame.remove());
// The assumption is that postMessage() is quicker
t.step_timeout(reject, 500);
frame.src = input;
});
assert_equals(event.data, result);
}, name);
});
// Failure cases
[
{
input: "data:text/html;base64,PHNjcmlwdD5wYXJlbnQucG9zdE1lc3NhZ2UoMywgJyonKTwvc2NyaXB0Pg=",
name: "base64 with incorrect padding",
},
{
input: "data:text/html;base64,PHNjcmlwdD5wYXJlbnQucG9zdE1lc3NhZ2UoNSwgJyonKTwvc2NyaXB0Pr-_",
name: "base64url is not supported"
},
{
input: "data:text/html;base64,%0BPHNjcmlwdD5wYXJlbnQucG9zdE1lc3NhZ2UoNywgJyonKTwvc2NyaXB0Pg==",
name: "Vertical tab in the input leads to an error"
}
].forEach(({ input, name }) => {
// Continue to use promise_test so they go sequentially
promise_test(async t => {
const event = await new Promise((resolve, reject) => {
self.addEventListener("message", t.step_func(reject), { once: true });
const frame = document.body.appendChild(document.createElement("iframe"));
t.add_cleanup(() => frame.remove());
// The assumption is that postMessage() is quicker
t.step_timeout(resolve, 500);
frame.src = input;
});
}, name);
});
// I found some of the interesting code point cases above through brute force:
//
// for (i = 0; i < 256; i++) {
// w(btoa("<script>parent.postMessage(5, '*')<\/script>" + String.fromCodePoint(i) + String.fromCodePoint(i)));
// }
|