-
Notifications
You must be signed in to change notification settings - Fork 3.3k
/
Copy pathHTMLElement-generic.html
93 lines (87 loc) · 3.31 KB
/
HTMLElement-generic.html
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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
<!DOCTYPE html>
<head>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support/helper.sub.js"></script>
</head>
<body>
<script>
const policy = trustedTypes.createPolicy("testpolicy", {
createScript: s => s,
createHTML: s => s,
createScriptURL: s => s,
});
function getTrusted(element, attr) {
const type = trustedTypes.getPropertyType(element, attr);
if (type == "TrustedScript") {
return policy.createScript("2+2");
} else if (type == "TrustedScriptURL") {
return policy.createScript("https://example.test/");
} else if (type == "TrustedHTML") {
return policy.createHTML("<b>hello</b>");
} else {
return "a simple string";
}
}
// This test will run a simple, TT-relevant assignment, in a number of
// circumstances. We've had issues where subtle difference in DOM behaviour -
// for example a connected element or a non-connected element - produce
// different results, and no test catching it because the tests were written
// to do it one particular way. So this test does one thing, but in all the
// different ways we can think of.
//
// - With TT disabled or enabled,
// - with any of the trusted types,
// - with a string or a TT value,
// - with a element that's connected to the DOM (or not).
//
// Run the set of tests, assuming that is_tt_enabled reflects whether Trusted
// Types is currently enabled (& enforced) or not.
function runTests(is_tt_enabled, description_suffix) {
for (const [element, attr] of [
[ 'script', 'src' ],
[ 'div', 'innerHTML' ],
[ 'iframe', 'srcdoc' ],
[ 'script', 'text' ],
[ 'script', 'innerText' ],
[ 'script', 'textContent' ],
]) {
const trusted = getTrusted(element, attr);
for (const value of [trusted, trusted.toString()]) {
for (const connected of [true, false]) {
const expect_exception = is_tt_enabled &&
value.constructor.name != trustedTypes.getPropertyType(element, attr);
test(t => {
const elem = document.createElement(element);
if (connected) document.body.appendChild(elem);
if (expect_exception) {
assert_throws_js(TypeError, _ => { elem[attr] = value; });
} else {
elem[attr] = value;
}
}, `${is_tt_enabled ? "TT enabled" : "TT disabled"}: ${element}.${attr}
= ${value.constructor.name} on a
${connected ? "connected" : "non-connected"} element
${description_suffix}`);
}
}
}
}
// Run the tests without TT first.
runTests(false, "");
// Now run the tests a second time, with TT enabled. To accomplish this, insert
// a suitable <meta> element.
const meta = document.createElement("meta");
meta.setAttribute("http-equiv", "Content-Security-Policy");
meta.setAttribute("content", "require-trusted-types-for 'script';");
document.head.appendChild(meta);
runTests(true, "");
// Remove the meta element and re-run the tests, expecting exceptions.
// That is, trusted types are still enforced. That behavior is required by
// <https://www.w3.org/TR/CSP3/#meta-element> 's note
// "Modifications to the content attribute of a meta element after the element
// has been parsed will be ignored.".
meta.remove();
runTests(true,
`after removing the "require-trusted-types-for 'script' directive`);
</script>