Skip to content

fix(media): sanitize animated image uploads#2524

Open
atishpatel wants to merge 2 commits into
mainfrom
atish/sanitize-animated-images
Open

fix(media): sanitize animated image uploads#2524
atishpatel wants to merge 2 commits into
mainfrom
atish/sanitize-animated-images

Conversation

@atishpatel

@atishpatel atishpatel commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Why

Animated PNG and WebP uploads preserved animation by bypassing desktop re-encoding, but that also preserved metadata rejected by the relay. Mobile rejected GIF, APNG, and animated WebP uploads instead of safely preparing them.

What

  • Structurally strip metadata from animated PNG and WebP uploads on desktop without decoding or flattening frames
  • Enable mobile GIF, APNG, and animated WebP uploads with shared lossless container sanitizers
  • Preserve animation timing, disposal, looping, and frame data while failing closed on malformed mobile input

Risk Assessment

Medium — this changes upload preprocessing for animated images on desktop and mobile. Static image handling is unchanged, and the relay remains the final policy authority.

References

  • Follow-up to fix(desktop): strip GIF metadata extensions before upload #2425 and related GIF scope fix fix(desktop): preserve GIF graphic control scope #2432
  • just dev: metadata-bearing APNG and WebP fixtures were rejected by the local relay with 422 before sanitization; sanitized APNG, WebP, and GIF uploads succeeded
  • Downloaded bytes matched the uploaded SHA-256 values for APNG (ba16043e…), WebP (75f510fd…), and GIF (80f4533b…)
  • The catjam fixtures remained 48×48 with 158 APNG/GIF frames and 157 WebP frames; Rust and Dart sanitizer outputs matched byte-for-byte for APNG and WebP
  • just ci
  • Isolated retry of the unrelated flaky buzz-agent cancellation regression passed after it failed once during the parallel pre-push hook
  • Screenshot not included: this is upload preprocessing with no visual UI delta, and the unbundled just dev Tauri process was not addressable by the macOS automation bridge

Review follow-up — 2026-07-23

Codex review found six actionable edge cases, all fixed:

  • Reject animated WebP files with non-identity EXIF orientation so metadata removal cannot change their rendered appearance
  • Reject animated PNG files with non-identity EXIF orientation for the same reason
  • Canonicalize recognized GIF loop extensions so extra sub-blocks cannot retain hidden metadata
  • Parse and sanitize nested WebP animation-frame chunks, with matching relay validation
  • Treat GIF application authentication codes as raw bytes so valid binary codes do not break mobile uploads
  • Reject animated PNG and WebP files with ICC profiles instead of silently changing their colors

A final Codex review found no remaining actionable correctness issues. just ci passed again after rebasing onto the latest main.

Generated with Codex

@atishpatel
atishpatel marked this pull request as ready for review July 23, 2026 14:33
@atishpatel
atishpatel requested a review from a team as a code owner July 23, 2026 14:33
atishpatel and others added 2 commits July 23, 2026 08:20
Co-authored-by: Codex <noreply@openai.com>
Co-authored-by: Codex <noreply@openai.com>
@atishpatel
atishpatel force-pushed the atish/sanitize-animated-images branch from f155646 to c8cfd93 Compare July 23, 2026 15:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant