/** * 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); }); });