Skip to content

Commit 46c95b3

Browse files
evilpiemoz-wptsync-bot
authored andcommitted
Sanitizer: Sort the result of the get() method.
Differential Revision: https://phabricator.services.mozilla.com/D267211 bugzilla-url: https://bugzilla.mozilla.org/show_bug.cgi?id=1989215 gecko-commit: 5f23528ad0d4305996911dc302d3a957e8cb5f8e gecko-reviewers: smaug
1 parent bbb3bb0 commit 46c95b3

File tree

4 files changed

+244
-178
lines changed

4 files changed

+244
-178
lines changed
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<script src="/resources/testharness.js"></script>
5+
<script src="/resources/testharnessreport.js"></script>
6+
<script src="./support/util.js"></script>
7+
</head>
8+
<body>
9+
<script>
10+
11+
const TEST_CASES = [
12+
[
13+
["b", "a"],
14+
["a", "b"]
15+
],
16+
[
17+
["c", "b", "a"],
18+
["a", "b", "c"]
19+
],
20+
[
21+
[{name: "b", namespace: null}, {name: "a", namespace: null}],
22+
[{name: "a", namespace: null}, {name: "b", namespace: null}]
23+
],
24+
[
25+
[{name: "_", namespace: "a"}, {name: "_", namespace: null}],
26+
[{name: "_", namespace: null}, {name: "_", namespace: "a"}]
27+
],
28+
[
29+
[{name: "_", namespace: "b"}, {name: "_", namespace: "a"}],
30+
[{name: "_", namespace: "a"}, {name: "_", namespace: "b"}]
31+
],
32+
[
33+
[{name: "a", namespace: "b"}, {name: "z", namespace: "a"}, {name: "b", namespace: "b"}],
34+
[{name: "z", namespace: "a"}, {name: "a", namespace: "b"}, {name: "b", namespace: "b"}],
35+
]
36+
];
37+
38+
for (const key of ["attributes", "removeAttributes", "elements", "removeElements", "replaceWithChildrenElements"]) {
39+
test(() => {
40+
for (const [input, expected] of TEST_CASES) {
41+
let s = new Sanitizer({
42+
[key]: input
43+
});
44+
assert_config(s.get(), {
45+
[key]: expected
46+
});
47+
}
48+
}, `Sorting of ${key}`);
49+
}
50+
51+
for (const key of ["attributes", "removeAttributes"]) {
52+
test(() => {
53+
for (const [input, expected] of TEST_CASES) {
54+
let s = new Sanitizer({
55+
elements: [{name: "_", [key]: input}]
56+
});
57+
assert_config(s.get(), {
58+
elements: [{name: "_", [key]: expected}]
59+
});
60+
}
61+
}, `Sorting of element's ${key}`);
62+
}
63+
64+
</script>
65+
</body>
66+
</html>

sanitizer-api/sanitizer-modifiers.tentative.html

Lines changed: 14 additions & 176 deletions
Original file line numberDiff line numberDiff line change
@@ -3,172 +3,10 @@
33
<head>
44
<script src="/resources/testharness.js"></script>
55
<script src="/resources/testharnessreport.js"></script>
6+
<script src="./support/util.js"></script>
67
</head>
78
<body>
89
<script>
9-
function is_same_sanitizer_name(a, b) {
10-
return a.name === b.name && a.namespace === b.namespace;
11-
}
12-
13-
// https://pr-preview.s3.amazonaws.com/otherdaniel/purification/pull/296.html#sanitizerconfig-valid
14-
function assert_config_is_valid(config) {
15-
// The config has either an elements or a removeElements key, but not both.
16-
assert_false(
17-
"elements" in config && "removeElements" in config,
18-
"Either elements or a removeElements, but not both",
19-
);
20-
assert_true(
21-
"elements" in config || "removeElements" in config,
22-
"Either elements or a removeElements",
23-
);
24-
25-
// The config has either an attributes or a removeAttributes key, but not both.
26-
assert_false(
27-
"attributes" in config && "removeAttributes" in config,
28-
"Either attributes or a removeAttributes, but not both",
29-
);
30-
assert_true(
31-
"attributes" in config || "removeAttributes" in config,
32-
"Either attributes or removeAttributes",
33-
);
34-
35-
// If both config[elements] and config[replaceWithChildrenElements] exist, then the difference of config[elements] and config[replaceWithChildrenElements] is empty.
36-
if (config.elements && config.replaceWithChildrenElements) {
37-
for (let element of config.elements) {
38-
assert_false(
39-
config.replaceWithChildrenElements.some((replaceElement) =>
40-
is_same_sanitizer_name(element, replaceElement),
41-
),
42-
`replaceWithChildrenElements should not contain ${element.name}`,
43-
);
44-
}
45-
}
46-
47-
// If both config[removeElements] and config[replaceWithChildrenElements] exist, then the difference of config[removeElements] and config[replaceWithChildrenElements] is empty.
48-
if (config.removeElements && config.replaceWithChildrenElements) {
49-
for (let removeElement of config.removeElements) {
50-
assert_false(
51-
config.replaceWithChildrenElements.some((replaceElement) =>
52-
is_same_sanitizer_name(removeElement, replaceElement),
53-
),
54-
`replaceWithChildrenElements should not contain ${removeElement.name}`,
55-
);
56-
}
57-
}
58-
59-
// If config[attributes] exists:
60-
if (config.attributes) {
61-
} else {
62-
// config[dataAttributes] does not exist.
63-
assert_false("dataAttributes" in config, "dataAttributes does not exist");
64-
}
65-
}
66-
67-
function assert_config(config, expected) {
68-
const PROPERTIES = [
69-
"attributes",
70-
"removeAttributes",
71-
"elements",
72-
"removeElements",
73-
"replaceWithChildrenElements",
74-
"comments",
75-
"dataAttributes",
76-
];
77-
78-
// Prevent some typos in the expected config.
79-
for (let key of Object.keys(expected)) {
80-
assert_in_array(key, PROPERTIES, "expected");
81-
}
82-
for (let key of Object.keys(config)) {
83-
assert_in_array(key, PROPERTIES, "config");
84-
}
85-
86-
assert_config_is_valid(config);
87-
88-
// XXX dataAttributes
89-
// XXX comments
90-
// XXX duplications
91-
// XXX other consistency checks
92-
93-
function assert_attrs(key, config, expected, prefix = "config") {
94-
// XXX we allow specifying only a subset for expected.
95-
if (!(key in expected)) {
96-
return;
97-
}
98-
99-
if (expected[key] === undefined) {
100-
assert_false(key in config, `Unexpected '${key}' in ${prefix}`);
101-
return;
102-
}
103-
104-
assert_true(key in config, `Missing '${key}' from ${prefix}`);
105-
assert_equals(config[key]?.length, expected[key].length, `${prefix}.${key}.length`);
106-
for (let i = 0; i < expected[key].length; i++) {
107-
let attribute = expected[key][i];
108-
if (typeof attribute === "string") {
109-
assert_object_equals(
110-
config[key][i],
111-
{ name: attribute, namespace: null },
112-
`${prefix}.${key}[${i}] should match`,
113-
);
114-
} else {
115-
assert_object_equals(
116-
config[key][i],
117-
attribute,
118-
`${prefix}.${key}[${i}] should match`,
119-
);
120-
}
121-
}
122-
}
123-
124-
assert_attrs("attributes", config, expected);
125-
assert_attrs("removeAttributes", config, expected);
126-
127-
function assert_elems(key) {
128-
if (!(key in expected)) {
129-
return;
130-
}
131-
132-
if (expected[key] === undefined) {
133-
assert_false(key in config, `Unexpected '${key}' in config`);
134-
return;
135-
}
136-
137-
assert_true(key in config, `Missing '${key}' from config`);
138-
assert_equals(config[key]?.length, expected[key].length, `${key}.length`);
139-
140-
const XHTML_NS = "http://www.w3.org/1999/xhtml";
141-
142-
for (let i = 0; i < expected[key].length; i++) {
143-
let element = expected[key][i];
144-
// To make writing tests a bit easier we also support the shorthand string syntax.
145-
if (typeof element === "string") {
146-
let extra = key === "elements" ? { removeAttributes: [] } : { };
147-
assert_object_equals(
148-
config[key][i],
149-
{ name: element, namespace: XHTML_NS, ...extra },
150-
`${key}[${i}] should match`,
151-
);
152-
} else {
153-
if (key === "elements") {
154-
assert_equals(config[key][i].name, element.name, `${key}[${i}].name should match`);
155-
let ns = "namespace" in element ? element.namespace : XHTML_NS;
156-
assert_equals(config[key][i].namespace, ns, `${key}[${i}].namespace should match`);
157-
158-
assert_attrs("attributes", config[key][i], element, `config.elements[${i}]`);
159-
assert_attrs("removeAttributes", config[key][i], element, `config.elements[${i}]`);
160-
} else {
161-
assert_object_equals(config[key][i], element, `${key}[${i}] should match`);
162-
}
163-
}
164-
}
165-
}
166-
167-
assert_elems("elements");
168-
assert_elems("removeElements");
169-
assert_elems("replaceWithChildrenElements");
170-
}
171-
17210
const NS = "http://example.org/";
17311

17412
test(() => {
@@ -339,19 +177,19 @@
339177

340178
assert_true(s.removeAttribute("dir"));
341179
assert_config(s.get(), {
342-
removeAttributes: ["title", "dir"],
180+
removeAttributes: ["dir", "title"],
343181
elements: [{ name: "div", attributes: ["class"], removeAttributes: ["id"] }],
344182
});
345183

346184
assert_true(s.removeAttribute("id"));
347185
assert_config(s.get(), {
348-
removeAttributes: ["title", "dir", "id"],
186+
removeAttributes: ["dir", "id", "title"],
349187
elements: [{ name: "div", attributes: ["class"], removeAttributes: [] }],
350188
});
351189

352190
assert_true(s.removeAttribute("class"));
353191
assert_config(s.get(), {
354-
removeAttributes: ["title", "dir", "id", "class"],
192+
removeAttributes: ["class", "dir", "id", "title"],
355193
elements: [{ name: "div", attributes: [], removeAttributes: [] }],
356194
});
357195
}, "sanitizer.removeAttribute() with global removeAttributes and elements");
@@ -364,13 +202,13 @@
364202

365203
assert_false(s.removeElement("span"));
366204
assert_config(s.get(), {
367-
elements: ["p", { name: "p", namespace: NS }],
205+
elements: [{ name: "p", namespace: NS }, "p"],
368206
replaceWithChildrenElements: ["b"],
369207
});
370208

371209
assert_true(s.removeElement("b"));
372210
assert_config(s.get(), {
373-
elements: ["p", { name: "p", namespace: NS }],
211+
elements: [{ name: "p", namespace: NS }, "p"],
374212
replaceWithChildrenElements: [],
375213
});
376214

@@ -395,25 +233,25 @@
395233

396234
assert_false(s.removeElement("p"));
397235
assert_config(s.get(), {
398-
removeElements: ["p", { name: "p", namespace: NS }],
236+
removeElements: [{ name: "p", namespace: NS }, "p"],
399237
replaceWithChildrenElements: ["b"],
400238
});
401239

402240
assert_false(s.removeElement({ name: "p", namespace: NS }));
403241
assert_config(s.get(), {
404-
removeElements: ["p", { name: "p", namespace: NS }],
242+
removeElements: [{ name: "p", namespace: NS }, "p"],
405243
replaceWithChildrenElements: ["b"],
406244
});
407245

408246
assert_true(s.removeElement("span"));
409247
assert_config(s.get(), {
410-
removeElements: ["p", { name: "p", namespace: NS }, "span"],
248+
removeElements: [{ name: "p", namespace: NS }, "p", "span"],
411249
replaceWithChildrenElements: ["b"],
412250
});
413251

414252
assert_true(s.removeElement("b"));
415253
assert_config(s.get(), {
416-
removeElements: ["p", { name: "p", namespace: NS }, "span", "b"],
254+
removeElements: [{ name: "p", namespace: NS }, "b", "p", "span"],
417255
replaceWithChildrenElements: [],
418256
});
419257
}, "sanitizer.removeElement() with global removeElements");
@@ -438,7 +276,7 @@
438276

439277
assert_true(s.replaceElementWithChildren("b"));
440278
assert_config(s.get(), {
441-
replaceWithChildrenElements: ["a", "span", "b"],
279+
replaceWithChildrenElements: ["a", "b", "span"],
442280
elements: [],
443281
});
444282
}, "sanitizer.replaceElementWithChildren() with global elements");
@@ -463,7 +301,7 @@
463301

464302
assert_true(s.replaceElementWithChildren("b"));
465303
assert_config(s.get(), {
466-
replaceWithChildrenElements: ["a", "span", "b"],
304+
replaceWithChildrenElements: ["a", "b", "span"],
467305
removeElements: [],
468306
});
469307
}, "sanitizer.replaceElementWithChildren() with global removeElements");
@@ -482,13 +320,13 @@
482320

483321
assert_true(s.allowElement({name: "a", namespace: NS}));
484322
assert_config(s.get(), {
485-
elements: ["a", {name: "a", namespace: NS}],
323+
elements: [{name: "a", namespace: NS}, "a"],
486324
replaceWithChildrenElements: ["b"]
487325
});
488326

489327
assert_true(s.allowElement("b"));
490328
assert_config(s.get(), {
491-
elements: ["a", {name: "a", namespace: NS}, "b"],
329+
elements: [{name: "a", namespace: NS}, "a", "b"],
492330
replaceWithChildrenElements: []
493331
});
494332
}, "sanitizer.allowElement() with global elements");

sanitizer-api/sanitizer-removeUnsafe.tentative.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
"removeElements": [
2323
{
2424
"namespace": "http://www.w3.org/1999/xhtml",
25-
"name": "script"
25+
"name": "embed"
2626
},
2727
{
2828
"namespace": "http://www.w3.org/1999/xhtml",
@@ -38,7 +38,7 @@
3838
},
3939
{
4040
"namespace": "http://www.w3.org/1999/xhtml",
41-
"name": "embed"
41+
"name": "script"
4242
},
4343
{
4444
"namespace": "http://www.w3.org/2000/svg",

0 commit comments

Comments
 (0)