/**
* Property tests for the markdown tokenizer (markdown.ts) and the
* XSS-safe DOM renderer built on top of it (content-parser.ts).
*
* These are fuzz-style invariants, not example-based checks:
* - the parsers never throw on arbitrary input
* - the DOM they build never contains a ",
"[click](javascript:alert(1))",
"[click](JaVaScRiPt:alert(1))",
"[click](data:text/html,)",
"[click](vbscript:msgbox(1))",
"
",
'x',
"javascript://alert(1)",
"**
**",
"[xss]( javascript:alert(1) )",
);
fc.assert(
fc.property(xssShapes, (s) => {
const host = document.createElement("div");
expect(() => host.appendChild(renderInlineContent(s))).not.toThrow();
assertDomIsSafe(host);
}),
{ numRuns: 10 },
);
});
});
describe("bounded time on pathological input", () => {
const BUDGET_MS = 3000;
it("a long run of unmatched '[' stays within budget", () => {
const input = "[".repeat(5000);
const start = Date.now();
expect(() => renderMessageContent(input)).not.toThrow();
expect(Date.now() - start).toBeLessThan(BUDGET_MS);
});
it("a long run of unmatched '*' stays within budget", () => {
const input = "*".repeat(5000);
const start = Date.now();
expect(() => renderMessageContent(input)).not.toThrow();
expect(Date.now() - start).toBeLessThan(BUDGET_MS);
});
it("a long run of unmatched '(' stays within budget", () => {
const input = "[x](".repeat(5000);
const start = Date.now();
expect(() => renderMessageContent(input)).not.toThrow();
expect(Date.now() - start).toBeLessThan(BUDGET_MS);
});
it("deeply nested emphasis stays within budget (MAX_DEPTH guards recursion)", () => {
const input = "*".repeat(2000) + "x" + "*".repeat(2000);
const start = Date.now();
expect(() => renderMessageContent(input)).not.toThrow();
expect(Date.now() - start).toBeLessThan(BUDGET_MS);
});
it("a long mix of brackets and parens stays within budget", () => {
const input = "[".repeat(2500) + "(".repeat(2500);
const start = Date.now();
expect(() => renderMessageContent(input)).not.toThrow();
expect(Date.now() - start).toBeLessThan(BUDGET_MS);
});
});