blob: 6b0066570043cf320a9b3a58c30d6afa88cc1ec6 [file] [log] [blame]
<!DOCTYPE html>
<head>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
</head>
<body>
<script>
// This is a set of tests that try to make sure various ways of setting
// attributes (directly; via an attribute node; etc.) are all being treated
// identically. For background, se::
// https://github.com/w3c/webappsec-trusted-types/issues/47
const elems = ["div", "script", "embed", "iframe"];
const attrs = ["src", "srcdoc", "onclick", "bla"];
const policy_callback = s => ("" + s + " [policy]");
const policy = trustedTypes.createPolicy("policy", {
"createHTML": policy_callback,
"createScript": policy_callback,
"createScriptURL": policy_callback,
});
// Returns either the string-ified result value of fn, or an exception type.
function try_get(fn) {
try {
return "" + fn();
} catch(e) {
return "" + e.name;
}
}
// Returns a 'trusted' version of value, if element.attribute requires it.
function trusted(element, attribute, value) {
switch (trustedTypes.getAttributeType(element, attribute)) {
case 'TrustedHTML': value = policy.createHTML(value); break;
case 'TrustedScript': value = policy.createScript(value); break;
case 'TrustedScriptURL': value = policy.createScriptURL(value); break;
}
return value;
}
for (elem of elems) {
for (attr of attrs) {
const reference = try_get(_ => {
const e = document.createElement(elem);
e.setAttribute(attr, "hello");
return e.getAttribute(attr);
});
// Event handlers (like "onclick") apply to all elements, so we don't
// really have 'harmless' element we can attach them to. Hence this test
// case doesn't apply.
if (attr != "onclick") {
test(t => {
const harmless = document.createElement("div");
harmless.setAttribute(attr, "hello");
const node = harmless.getAttributeNode(attr);
harmless.removeAttributeNode(node);
const actual = try_get(_ => {
const e = document.createElement(elem);
e.setAttributeNode(node);
return e.getAttribute(attr);
});
assert_equals(actual, reference);
}, `Set attribute via attribute node on ${elem}.${attr}.`);
}
test(t => {
const e = document.createElement(elem);
e.setAttribute(attr, trusted(elem, attr, "123"));
const actual = try_get(_ => {
e.getAttributeNode(attr).value = "hello";
return e.getAttribute(attr);
});
assert_equals(actual, reference);
}, `Set attribute via attributenode.value on ${elem}.${attr}.`);
test(t => {
const e = document.createElement(elem);
const attrnode = document.createAttribute(attr);
attrnode.value = "hello";
const actual = try_get(_ => {
e.attributes.setNamedItem(attrnode);
return e.getAttribute(attr);
});
assert_equals(actual, reference);
}, `Set attribute via NamedNodeMap.setNamedItem on ${elem}.${attr}.`);
}
}
</script>
</body>