mirror of
https://github.com/storytold/photocraft.git
synced 2026-11-02 22:30:20 -06:00
Profile::content_hash is a fixed-key 64-bit SipHash of the ICC bytes, so a crafted profile can share another profile's hash (about 2^32 work). Two places took an equal hash as proof of an identical profile: - transform::cached keyed its process-wide cache on the two hashes and the options, so a colliding profile was handed the other profile's cached transform and converted with the wrong colours. - Profile::same_colors returned true on equal hashes, so a colliding profile was taken for the other one and a needed conversion was skipped. Add Profile::same_bytes, which compares the ICC bytes (an Arc pointer check first, then the hash, then the bytes). same_colors uses it instead of the hash. Each transform cache entry now keeps the ICC bytes of its two profiles; a hit counts only when they match, and a colliding pair gets its own transform without replacing the cached entry. The transform is built after the cache lock is released, as before. The regression tests give Display P3 the content hash of sRGB (a stand-in for a found collision): before the fix, same_colors called them the same and the cache returned sRGB's transform for P3; now both see P3's colours. Fixes #8613 Co-authored-by: John Turnbach <jturnbach@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>