| <!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> |