@instructure/platform-sanitize 0.3.11 → 0.3.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sanitizeHtml.browser.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/sanitizeHtml.browser.test.ts"],"names":[],"mappings":""}
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import c from "dompurify";
|
|
2
|
-
const
|
|
2
|
+
const p = /* @__PURE__ */ new Set([
|
|
3
3
|
// layout
|
|
4
4
|
"display",
|
|
5
5
|
"float",
|
|
@@ -106,6 +106,13 @@ const g = /* @__PURE__ */ new Set([
|
|
|
106
106
|
"border-style",
|
|
107
107
|
"border-width",
|
|
108
108
|
"border-radius",
|
|
109
|
+
// Chrome's CSSOM expands border-radius to these four longhands when iterating
|
|
110
|
+
// element.style — the shorthand itself never appears in the iterator, so the
|
|
111
|
+
// hook would strip all four corners unless they are explicitly listed here.
|
|
112
|
+
"border-top-left-radius",
|
|
113
|
+
"border-top-right-radius",
|
|
114
|
+
"border-bottom-right-radius",
|
|
115
|
+
"border-bottom-left-radius",
|
|
109
116
|
"border-collapse",
|
|
110
117
|
"border-spacing",
|
|
111
118
|
"border-top",
|
|
@@ -130,6 +137,9 @@ const g = /* @__PURE__ */ new Set([
|
|
|
130
137
|
"outline-color",
|
|
131
138
|
"outline-style",
|
|
132
139
|
"outline-width",
|
|
140
|
+
// outline-offset is not part of the `outline` shorthand, so it must be listed
|
|
141
|
+
// separately or it is stripped when authored on its own (focus-ring styling).
|
|
142
|
+
"outline-offset",
|
|
133
143
|
// list
|
|
134
144
|
"list-style",
|
|
135
145
|
"list-style-image",
|
|
@@ -225,7 +235,7 @@ const g = /* @__PURE__ */ new Set([
|
|
|
225
235
|
"caret-color",
|
|
226
236
|
"accent-color",
|
|
227
237
|
"appearance"
|
|
228
|
-
]),
|
|
238
|
+
]), m = /* @__PURE__ */ new Set([
|
|
229
239
|
"src",
|
|
230
240
|
"href",
|
|
231
241
|
"action",
|
|
@@ -236,7 +246,7 @@ const g = /* @__PURE__ */ new Set([
|
|
|
236
246
|
"cite",
|
|
237
247
|
"longdesc",
|
|
238
248
|
"xlink:href"
|
|
239
|
-
]), u = /^\s*(\/\/|\\)/,
|
|
249
|
+
]), u = /^\s*(\/\/|\\)/, w = [
|
|
240
250
|
"background",
|
|
241
251
|
"background-image",
|
|
242
252
|
"list-style",
|
|
@@ -245,7 +255,7 @@ const g = /* @__PURE__ */ new Set([
|
|
|
245
255
|
// content: url(...) triggers an HTTP GET even on non-pseudo elements in some
|
|
246
256
|
// browsers; strip it as defense-in-depth against tracking-pixel exfiltration.
|
|
247
257
|
"content"
|
|
248
|
-
],
|
|
258
|
+
], h = /url\s*\(\s*['"]?(?:[a-z][a-z0-9+\-.]*:|\/\/)/i, y = /* @__PURE__ */ new Set([
|
|
249
259
|
"allow-downloads",
|
|
250
260
|
"allow-forms",
|
|
251
261
|
"allow-modals",
|
|
@@ -258,7 +268,7 @@ const g = /* @__PURE__ */ new Set([
|
|
|
258
268
|
"allow-scripts",
|
|
259
269
|
"allow-storage-access-by-user-activation",
|
|
260
270
|
"allow-top-navigation-by-user-activation"
|
|
261
|
-
]),
|
|
271
|
+
]), d = {
|
|
262
272
|
ADD_TAGS: ["iframe"],
|
|
263
273
|
ADD_ATTR: [
|
|
264
274
|
"allowfullscreen",
|
|
@@ -307,7 +317,7 @@ function k() {
|
|
|
307
317
|
const e = t.style, o = [];
|
|
308
318
|
for (let n = 0; n < e.length; n++) {
|
|
309
319
|
const a = e.item(n);
|
|
310
|
-
|
|
320
|
+
p.has(a) || o.push(a);
|
|
311
321
|
}
|
|
312
322
|
for (const n of o) e.removeProperty(n);
|
|
313
323
|
const r = /* @__PURE__ */ new Set([
|
|
@@ -321,13 +331,13 @@ function k() {
|
|
|
321
331
|
"revert-layer"
|
|
322
332
|
]), s = e.getPropertyValue("position").trim().toLowerCase();
|
|
323
333
|
s && !r.has(s) && e.removeProperty("position");
|
|
324
|
-
for (const n of
|
|
334
|
+
for (const n of w) {
|
|
325
335
|
const a = e.getPropertyValue(n);
|
|
326
|
-
a &&
|
|
336
|
+
a && h.test(a) && e.removeProperty(n);
|
|
327
337
|
}
|
|
328
338
|
e.length === 0 && t.removeAttribute("style");
|
|
329
339
|
}), i.addHook("uponSanitizeAttribute", (t, e) => {
|
|
330
|
-
|
|
340
|
+
m.has(e.attrName) && u.test(e.attrValue) && (e.keepAttr = !1);
|
|
331
341
|
}), i.addHook("afterSanitizeAttributes", (t) => {
|
|
332
342
|
if (!(t instanceof Element) || !t.hasAttribute("srcset")) return;
|
|
333
343
|
(t.getAttribute("srcset") ?? "").split(",").map((r) => r.trim().split(/\s+/)[0]).some((r) => u.test(r)) && t.removeAttribute("srcset");
|
|
@@ -338,16 +348,17 @@ function k() {
|
|
|
338
348
|
o.add("noopener"), t.setAttribute("rel", [...o].join(" "));
|
|
339
349
|
}), i.addHook("afterSanitizeAttributes", (t) => {
|
|
340
350
|
if (!(t instanceof Element) || t.tagName !== "IFRAME" || !t.hasAttribute("sandbox")) return;
|
|
341
|
-
const o = (t.getAttribute("sandbox") ?? "").toLowerCase().split(/\s+/).filter(Boolean), r = o.filter((s) =>
|
|
351
|
+
const o = (t.getAttribute("sandbox") ?? "").toLowerCase().split(/\s+/).filter(Boolean), r = o.filter((s) => y.has(s));
|
|
342
352
|
r.length !== o.length && t.setAttribute("sandbox", r.join(" "));
|
|
343
353
|
}), i);
|
|
344
354
|
}
|
|
345
|
-
function R(t) {
|
|
355
|
+
function R(t, e) {
|
|
346
356
|
if (typeof window > "u")
|
|
347
357
|
throw new Error("sanitizeHtml requires a DOM environment (window is not defined)");
|
|
348
|
-
|
|
358
|
+
const o = e != null && e.allowFormAttributeNames ? { ...d, SANITIZE_DOM: !1 } : d;
|
|
359
|
+
return k().sanitize(t ?? "", o);
|
|
349
360
|
}
|
|
350
|
-
const
|
|
361
|
+
const f = /* @__PURE__ */ new Set(["http:", "https:", "mailto:", "tel:"]), l = "http://platform-sanitize.invalid/", b = /^\s*\/\//, g = (
|
|
351
362
|
// oxlint-disable-next-line no-control-regex -- intentional security guard
|
|
352
363
|
/^[\u0000-\u0020\u007F-\u00A0\u2000-\u200F\u2028\u2029\u202F\u205F\u2060\u3000\uFEFF]*(?:javascript|data|vbscript|file):/i
|
|
353
364
|
), A = {
|
|
@@ -385,14 +396,14 @@ function E(t) {
|
|
|
385
396
|
function S(t) {
|
|
386
397
|
if (!t || !t.trim()) return "about:blank";
|
|
387
398
|
const e = t.replace(/\\/g, "/");
|
|
388
|
-
if (
|
|
399
|
+
if (b.test(e) || g.test(e)) return "about:blank";
|
|
389
400
|
if (/&[#A-Za-z]/.test(e)) {
|
|
390
401
|
const o = E(e);
|
|
391
|
-
if (
|
|
402
|
+
if (b.test(o) || g.test(o))
|
|
392
403
|
return "about:blank";
|
|
393
404
|
try {
|
|
394
405
|
const r = new URL(o, l);
|
|
395
|
-
if (!r.href.startsWith(l) && !
|
|
406
|
+
if (!r.href.startsWith(l) && !f.has(r.protocol))
|
|
396
407
|
return "about:blank";
|
|
397
408
|
} catch {
|
|
398
409
|
return "about:blank";
|
|
@@ -400,7 +411,7 @@ function S(t) {
|
|
|
400
411
|
}
|
|
401
412
|
try {
|
|
402
413
|
const o = new URL(e, l);
|
|
403
|
-
return !
|
|
414
|
+
return !f.has(o.protocol) || (o.protocol === "http:" || o.protocol === "https:") && (o.username || o.password) ? "about:blank" : o.href.startsWith(l) ? t : e.replace(/[\x00-\x1F\u2028\u2029]/g, "").replace(/%250[9ad]/gi, "").replace(/%0[9ad]/gi, "");
|
|
404
415
|
} catch {
|
|
405
416
|
return "about:blank";
|
|
406
417
|
}
|
package/dist/sanitizeHtml.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sanitizeHtml.d.ts","sourceRoot":"","sources":["../src/sanitizeHtml.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"sanitizeHtml.d.ts","sourceRoot":"","sources":["../src/sanitizeHtml.ts"],"names":[],"mappings":"AAubA,wBAAgB,YAAY,CAC1B,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAC/B,OAAO,CAAC,EAAE;IAAE,uBAAuB,CAAC,EAAE,OAAO,CAAA;CAAE,GAC9C,MAAM,CASR"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@instructure/platform-sanitize",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.13",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.js",
|
|
@@ -17,25 +17,29 @@
|
|
|
17
17
|
"publishConfig": {
|
|
18
18
|
"access": "public"
|
|
19
19
|
},
|
|
20
|
-
"scripts": {
|
|
21
|
-
"build": "vite build",
|
|
22
|
-
"dev": "vite build --watch",
|
|
23
|
-
"test": "vitest run",
|
|
24
|
-
"test:watch": "vitest",
|
|
25
|
-
"test:coverage": "vitest run --coverage",
|
|
26
|
-
"type-check": "tsc --noEmit"
|
|
27
|
-
},
|
|
28
20
|
"peerDependencies": {
|
|
29
21
|
"dompurify": "^3.4.0"
|
|
30
22
|
},
|
|
31
23
|
"devDependencies": {
|
|
32
24
|
"@types/trusted-types": "^2.0.7",
|
|
25
|
+
"@vitest/browser": "^4.0.17",
|
|
26
|
+
"@vitest/browser-playwright": "^4.0.17",
|
|
33
27
|
"@vitest/coverage-v8": "^4.0.17",
|
|
34
28
|
"dompurify": "^3.4.0",
|
|
35
29
|
"jsdom": "^25.0.0",
|
|
30
|
+
"playwright": "^1.60.0",
|
|
36
31
|
"typescript": "^5.3.0",
|
|
37
32
|
"vite": "^6.0.0",
|
|
38
33
|
"vite-plugin-dts": "^4.0.0",
|
|
39
34
|
"vitest": "^4.0.0"
|
|
35
|
+
},
|
|
36
|
+
"scripts": {
|
|
37
|
+
"build": "vite build",
|
|
38
|
+
"dev": "vite build --watch",
|
|
39
|
+
"test": "vitest run",
|
|
40
|
+
"test:browser": "vitest run --config vitest.browser.config.ts",
|
|
41
|
+
"test:watch": "vitest",
|
|
42
|
+
"test:coverage": "vitest run --coverage",
|
|
43
|
+
"type-check": "tsc --noEmit"
|
|
40
44
|
}
|
|
41
|
-
}
|
|
45
|
+
}
|