summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/trusted-types/TrustedType-AttributeNodes.tentative.html
blob: 6b0066570043cf320a9b3a58c30d6afa88cc1ec6 (plain)
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
<!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>