aboutsummaryrefslogtreecommitdiff
path: root/src/lib/Utility/sanitizeHtml.test.ts
blob: 1094635e0f4c256872c239dc7b1a1693c16b3d9d (plain) (blame)
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
// @vitest-environment jsdom
import { describe, expect, it } from "vitest";
import { sanitizeFeedHtml } from "./sanitizeHtml";

describe("sanitizeFeedHtml", () => {
	// Behaviour gate: the formatting real feeds use must survive untouched.
	it("preserves entities, inline formatting and safe links", () => {
		expect(sanitizeFeedHtml("Fruits & Vegetables")).toBe(
			"Fruits & Vegetables",
		);
		expect(sanitizeFeedHtml("<i>italic</i> and <b>bold</b>")).toBe(
			"<i>italic</i> and <b>bold</b>",
		);
		expect(sanitizeFeedHtml("Vol. 1 <em>Ch.</em> 5")).toBe(
			"Vol. 1 <em>Ch.</em> 5",
		);
		expect(
			sanitizeFeedHtml('<a href="https://example.com/x">link</a>'),
		).toContain('href="https://example.com/x"');
		expect(sanitizeFeedHtml("line<br>break")).toContain("<br");
	});

	it("returns empty string for nullish input", () => {
		expect(sanitizeFeedHtml(undefined)).toBe("");
		expect(sanitizeFeedHtml(null)).toBe("");
		expect(sanitizeFeedHtml("")).toBe("");
	});

	// The fix: scripts, handlers, dangerous tags and URLs must be removed.
	it("strips scripts, event handlers and dangerous tags/urls", () => {
		const script = sanitizeFeedHtml("<script>alert(1)</script>safe");
		expect(script).not.toContain("script");
		expect(script).toContain("safe");

		const onerror = sanitizeFeedHtml("before<img src=x onerror=alert(1)>after");
		expect(onerror).not.toContain("onerror");
		expect(onerror).not.toContain("<img");
		expect(onerror).toContain("before");
		expect(onerror).toContain("after");

		expect(
			sanitizeFeedHtml('<a href="javascript:alert(1)">x</a>'),
		).not.toContain("javascript:");
		expect(
			sanitizeFeedHtml('<iframe src="https://evil.example.com"></iframe>'),
		).not.toContain("iframe");
		expect(
			sanitizeFeedHtml(
				'<meta http-equiv="refresh" content="0;url=https://evil.example.com">',
			),
		).not.toContain("meta");
		expect(sanitizeFeedHtml("<style>body{display:none}</style>")).not.toContain(
			"style",
		);
		expect(sanitizeFeedHtml('<div onclick="steal()">text</div>')).toBe("text");
	});
});