Primary finding
Misleading test name/comment: escapeXml will double-escape already-escaped entities, but test claims otherwise
- apps/web/lib/rss.test.ts:9-12
- apps/web/lib/rss.ts:14-16
The escapeXml implementation replaces all occurrences of &, <, >, ", ' in one pass. If given a pre-escaped entity like "&", it will still replace the leading '&' producing "&amp;". The test titled "does not double-escape pre-escaped entities" neither uses pre-escaped input nor verifies idempotence, and its comment about replacement order is inaccurate for a single-pass regex replace. This can mask future assumptions that escapeXml is idempotent.
Recommendation
Decide and document the contract: if callers always pass raw, unescaped text, rename the test (e.g., "escapes '&' before '<' without creating new escapable characters") and add a test clarifying that pre-escaped strings may be double-escaped. If idempotence on already-escaped entities is desired, update escapeXml to avoid escaping ampersands that already start a valid entity (e.g., use /&(?![a-zA-Z]+;|#\d+;|#x[0-9a-fA-F]+;)|[<>"']/g) and add a test asserting escapeXml("&") === "&".