Feed links are followed only when they are web addresses (#326)

An item's link and an enclosure's URL are the publisher's, stored as
written, and the page put them in href and window.open through esc(),
which escapes characters, not schemes: a javascript: or data: link
survived as Open the original, View in a new tab (for a file not on
disk), the Directory's item links and the v key. Show notes already
lose those schemes to ammonia; these four sinks were the exception.

webUrl() passes http(s) only, and each sink goes through it. A link
that fails it shows no link, as an item with none does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-23 13:07:47 +00:00
parent 62a2456dde
commit 708b69c083
6 changed files with 18 additions and 4 deletions

View File

@@ -27,6 +27,14 @@ test('esc makes text safe to put in markup and attributes', () => {
assert.equal(run('esc(undefined)'), '');
});
test('webUrl keeps only web addresses from a feed', () => {
assert.equal(run(`webUrl('https://example.com/a')`), 'https://example.com/a');
assert.equal(run(`webUrl('HTTP://example.com/')`), 'HTTP://example.com/');
for (const u of ['javascript:alert(1)', ' javascript:alert(1)', 'data:text/html,x', 'vbscript:x', '//example.com', ''])
assert.equal(run(`webUrl(${JSON.stringify(u)})`), null, u);
assert.equal(run('webUrl(null)'), null);
});
test('clock reads seconds as a player does', () => {
assert.equal(run('clock(0)'), '0:00');
assert.equal(run('clock(65)'), '1:05');