Source code
Revision control
Copy as Markdown
Other Tools
Test Info:
<!DOCTYPE HTML>
<title>Test sanitizer api</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" href="/tests/SimpleTest/test.css" />
<script type="text/javascript">
"use strict";
/* global Sanitizer */
// we're not done after "onload"
SimpleTest.waitForExplicitFinish();
(async function() {
// Ensure Sanitizer is not exposed when the pref is false
const isEnabled = SpecialPowers.getBoolPref("dom.security.sanitizer.enabled");
if (!isEnabled) {
ok(false, "This test should only be run with dom.security.sanitizer.enabled set to true");
SimpleTest.finish();
}
function* possibleInputTypes(inputStr) {
/* This generator function, given a string, yields all possible input objects
for our sanitizer API (string, docfragment, document).
*/
// 1) as string
yield ({testInput: inputStr, testType: "String" });
// 2) as DocumentFragment
let temp = document.createElement('template');
// asking eslint to skip this: innerHTML is safe for template elements.
temp.innerHTML = inputStr;
yield ({testInput: temp.content, testType: "DocumentFragment" });
// 3) as HTMLDocument
const parser = new DOMParser;
yield ({testInput: parser.parseFromString(inputStr, "text/html"), testType: "Document" });
}
// basic interface smoke test
ok(typeof Sanitizer === "function", "Sanitizer constructor exposed when preffed on");
const mySanitizer = new Sanitizer();
ok(mySanitizer, "Sanitizer constructor works");
ok(mySanitizer.sanitize, "sanitize function exists");
ok("setHTML" in Element.prototype, "Element.setHTML exists");
// testing sanitizer results
const testCases = [
{
testString: "<p>hello</p>",
testExpected: "<p>hello</p>",
sanitizerOptions: {}
},
{
// script element encoded to not confuse the HTML parser and end execution here
testString: "<p>second test</p><script>alert(1)\x3C/script>",
testExpected: "<p>second test</p>",
sanitizerOptions: {},
},
{
// test for the elements option
testString: "<p>hello <i>folks</i></p>",
testExpected: "<p>hello folks</p>",
sanitizerOptions: { elements: ["p"] },
},
{
// test for the replaceWithChildrenElements option
testString: "<p>hello <i>folks</i></p>",
testExpected: "<p>hello folks</p>",
sanitizerOptions: { replaceWithChildrenElements: ["i"] },
},
// TODO: Unknown attributes aren't supported yet.
// {
// // test for the allowAttributes option
// testString: `<p haha="lol">hello</p>`,
// testExpected: `<p haha="lol">hello</p>`,
// sanitizerOptions: { unknownMarkup: true, attributes: ["haha"] },
// },
{
// confirming the inverse
testString: `<p haha="lol">hello</p>`,
testExpected: `<p>hello</p>`,
sanitizerOptions: {},
},
{
// test for the removeAttributes option
testString: `<p title="dropme">hello</p>`,
testExpected: `<p>hello</p>`,
sanitizerOptions: { removeAttributes: ['title'] },
},
{
// confirming the inverse
testString: `<p title="dontdropme">hello</p>`,
testExpected: `<p title="dontdropme">hello</p>`,
sanitizerOptions: {},
},
{
// if an attribute is allowed and removed, the remove will take preference
testString: `<p title="lol">hello</p>`,
testExpected: `<p>hello</p>`,
sanitizerOptions: {
attributes: ["title"],
removeAttributes: ["title"],
},
},
];
const div = document.createElement("div");
for (let test of testCases) {
const {testString, testExpected, sanitizerOptions} = test;
const testSanitizer = new Sanitizer(sanitizerOptions);
for (let testInputAndType of possibleInputTypes(testString)) {
const {testInput, testType} = testInputAndType;
if (testType != "String") {
// test sanitize(document/fragment)
try {
div.innerHTML = "";
const docFragment = testSanitizer.sanitize(testInput);
div.append(docFragment);
is(div.innerHTML, testExpected, `Sanitizer.sanitize() should turn (${testType}) '${testInput}' into '${testExpected}'`);
}
catch (e) {
ok(false, 'Error in sanitize() test: ' + e)
}
}
else {
// test setHTML:
try {
div.setHTML(testString, { sanitizer: sanitizerOptions });
is(div.innerHTML, testExpected, `div.setHTML() should turn(${testType}) '${testInput}' into '${testExpected}'`);
}
catch (e) {
ok(false, 'Error in setHTML() test: ' + e)
}
}
}
}
SimpleTest.finish();
})();
</script>