Skip to content

Blob/File type: preserve user-supplied MIME verbatim (WHATWG File API)

27153ec
Select commit
Loading
Failed to load commit list.
Open

Blob/File type: preserve user-supplied MIME verbatim (WHATWG File API) #29258

Blob/File type: preserve user-supplied MIME verbatim (WHATWG File API)
27153ec
Select commit
Loading
Failed to load commit list.
Claude / Claude Code Review completed Apr 13, 2026 in 21m 7s

Code review found 2 important issues

Found 5 candidates, confirmed 3. See review comments for details.

Details

Severity Count
🔴 Important 2
🟡 Nit 0
🟣 Pre-existing 1
Severity File:Line Issue
🔴 Important src/bun.js/webcore/Blob.zig:3537-3548 dupeWithContentType: use-after-free guard is unreachable dead code
🔴 Important src/bun.js/VirtualMachine.zig:350-355 S3File construction paths still canonicalize MIME types
🟣 Pre-existing src/bun.js/webcore/Blob.zig:2937-2946 getSlice: content_type_was_set stays false for interned MIME types

Annotations

Check failure on line 3548 in src/bun.js/webcore/Blob.zig

See this annotation in the file changed.

@claude claude / Claude Code Review

dupeWithContentType: use-after-free guard is unreachable dead code

The use-after-free fix in `dupeWithContentType` is unreachable dead code: `duped.setNotHeapAllocated()` sets `#ref_count` to zero, but both subsequent guards check `duped.isHeapAllocated()` (which tests `raw_value != 0`), so both branches are permanently false. The `mimeTypeInternedValue` substitution this PR introduces into that block never executes, and when `include_content_type=true` with a heap-allocated `content_type`, the pointer is silently shared between the original and duped blob with

Check failure on line 355 in src/bun.js/VirtualMachine.zig

See this annotation in the file changed.

@claude claude / Claude Code Review

S3File construction paths still canonicalize MIME types

S3File construction paths still call the old `mimeType()` helper, which routes through `MimeType.Compact.toMimeType()` and silently rewrites `text/plain` → `text/plain;charset=utf-8`, etc. Any S3-backed blob created with a well-known MIME type will have its `.type` property canonicalized, violating the same WHATWG File API semantics this PR fixes. Fix by replacing `mimeType(str.slice())` with `mimeTypeInternedValue(slice)` at both S3File.zig lines 286 and 330, matching the pattern applied throug

Check notice on line 2946 in src/bun.js/webcore/Blob.zig

See this annotation in the file changed.

@claude claude / Claude Code Review

getSlice: content_type_was_set stays false for interned MIME types

In `blob.slice(start, end, type)`, passing a known MIME type (e.g. `'text/plain'`) leaves `content_type_was_set=false` on the returned slice when the parent blob has no type, causing `getMimeTypeOrContentType()` to skip the user-supplied type and return the store MIME instead — producing wrong Content-Type headers on HTTP responses. This is a pre-existing issue; the old `mimeType()` path had the same omission, and the PR modifies this exact code without fixing the flag.