Blob/File type: preserve user-supplied MIME verbatim (WHATWG File API) #29258
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
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
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
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.
Loading