tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

sanitizer-names.tentative.html (4112B)


      1 <!DOCTYPE html>
      2 <html>
      3 <head>
      4  <script src="/resources/testharness.js"></script>
      5  <script src="/resources/testharnessreport.js"></script>
      6 </head>
      7 <body>
      8 <script>
      9  // Quick sanity tests for namespaced elements.
     10  // Each test case is a duo or triplet:
     11  // - a Sanitizer config string for an element.
     12  // - an HTML probe string.
     13  // - the expected result. (If different from the probe.)
     14  const SVG_NS = "http://www.w3.org/2000/svg";
     15  const MATHML_NS = "http://www.w3.org/1998/Math/MathML";
     16  [
     17    [ "p", "<p>Hello</p>" ],
     18    [ "svg", "<svg>Hello</svg>", "" ],
     19    [ { name: "svg", namespace: SVG_NS }, "<svg>Hello</svg>" ],
     20    [ "math", "<math>Hello</math>", "" ],
     21    [ { name: "math", namespace: SVG_NS }, "<math>Hello</math>", "" ],
     22    [ { name: "math", namespace: MATHML_NS }, "<math>Hello</math>" ],
     23  ].forEach(([elem, probe, expected], index) => {
     24    test(t => {
     25      const div = document.createElement("div");
     26      div.setHTML(probe, {sanitizer: {elements: [elem]}});
     27      assert_equals(div.innerHTML, expected ?? probe);
     28    }, `Namespaced elements #${index}: elements: [${JSON.stringify(elem)}]`);
     29  });
     30 
     31  // Same for attributes:
     32  const XLINK_NS = "http://www.w3.org/1999/xlink";
     33  [
     34    [ { name: "style"}, "<p style=\"bla\"></p>" ],
     35    [ { name: "href"}, "<p href=\"bla\"></p>" ],
     36 
     37    // In HTML content, the HTML parser parses "xlink:href" as an attribute
     38    // named "xlink:href" in the null namespace.
     39    [ { name: "xlink:href"}, "<p xlink:href=\"bla\"></p>" ],
     40    [ { name: "href", namespace: XLINK_NS}, "<p xlink:href=\"bla\"></p>", "<p></p>" ],
     41    [ { name: "href", namespace: XLINK_NS}, "<p href='bla'></p>", "<p></p>" ],
     42    [ { name: "href"}, "<p xlink:href='bla'></p>", "<p></p>" ],
     43 
     44    // For "foreign elements" like <svg>, the HTML parser parses "xlink:href" as
     45    // an attribtue named "href" in the XLink namespace.
     46    [ { name: "xlink:href"}, "<svg xlink:href=\"bla\"></svg>", "<svg></svg>" ],
     47    [ { name: "href", namespace: XLINK_NS}, "<svg xlink:href=\"bla\"></svg>" ],
     48    [ { name: "href", namespace: XLINK_NS}, "<svg href='bla'></svg>", "<svg></svg>" ],
     49    [ { name: "href"}, "<svg xlink:href='bla'></svg>", "<svg></svg>" ],
     50  ].forEach(([attr, probe, expected], index) => {
     51    test(t => {
     52      const options = {attributes: [attr],
     53                       elements: ["p", {name: "svg", namespace: SVG_NS}]};
     54      const template = document.createElement("template");
     55      template.setHTML(probe, {sanitizer: options});
     56      assert_equals(template.content.firstElementChild.outerHTML, expected ?? probe);
     57    }, `Namespaced attributes #${index}: attributes: [${JSON.stringify(attr)}]`);
     58  });
     59 
     60  // Test for namespaced attribute inside namespace element
     61  test(t => {
     62    const probe = `<svg><a xlink:href="bla"></a></svg>`;
     63 
     64    const options = {
     65      elements: [
     66        {name: "svg", namespace: SVG_NS},
     67        {name: "a", namespace: SVG_NS, attributes: [
     68          { name: "href", namespace: XLINK_NS }
     69        ]}
     70      ]};
     71    const template = document.createElement("template");
     72    template.setHTML(probe, {sanitizer: options});
     73    assert_equals(template.innerHTML, probe);
     74  }, "Namespaced attribute xlink:href inside SVG tree");
     75 
     76  // Names are case-senstive. Most element and attribute names are
     77  // lower-cased, but "foreign content" like SVG and MathML have some
     78  // mixed-cased names. Check this is supported.
     79  [
     80    [ "feBlend", "<feBlend></feBlend>" ],
     81    [ "feColorMatrix", "<feColorMatrix></feColorMatrix>" ],
     82    [ "textPath", "<textPath></textPath>" ],
     83  ].forEach(([elem, probe], index) => {
     84    const sanitize = (elem, probe) => {
     85      const options = {elements: [
     86          { name: "svg", namespace: SVG_NS },
     87          { name: elem, namespace: SVG_NS }
     88        ]};
     89      const template = document.createElement("template");
     90      template.setHTML(`<svg>${probe}</svg>`, {sanitizer: options});
     91      return template.content.firstElementChild.innerHTML;
     92    };
     93    test(t => {
     94      assert_equals(sanitize(elem, probe), probe);
     95    }, `Mixed-case element names #${index}: "svg:${elem}"`);
     96  });
     97 </script>
     98 </body>
     99 </html>