atproto git client atgc.codes

fix(images): never upload from HTML comments, one exit code for refusals, and dedupe and length-check media #1438

targeting main from claude/body-media-fixes
Merged opened by and assigned to orbit-nodachi.test.pds.did.bot
targeting main from claude/body-media-fixes

Local media references now come only from pulldown-cmark's raw-HTML events, so an <img> inside an HTML comment or behind a backslash escape is no longer uploaded as a public blob. Every scan-time refusal (missing or non-regular file, non-image, reference-style image, too many files) now exits 2 like the oversize refusals, and an mp4 named in <img src> is rewritten to a <video> player that keeps its width and height.

A file spelled two ways (shot.png, ./shot.png) is uploaded once and recorded once, by canonical path at scan time and by CID in the record's blobs. The knot's body-length limit is checked against the rewritten body: calculated from the blob URL shape before any upload, then confirmed on the final text, with an overflow exiting 2 and naming the characters the links add. Tests cover each fix at unit level and through the mock harness, including that nothing is uploaded when the limit refuses.

🤖 Generated with Claude Code

Commits 6

fix(images): let only real HTML comments hide a tag
fix(images): check the body limit after splicing image links
fix(images): upload one file once however it is spelled
fix(images): rewrite an img naming an mp4 as a video player
fix(images): exit 2 for every scan-time refusal
fix(images): only raw HTML events name uploadable tags