spawn: respect Blob offset/size when a sliced Bun.file is used as stdin

Closed
DY
1mo ago
+185-33

What

Bun.spawn({ stdin: Bun.file(path).slice(5, 10) }) was feeding the entire file to the child's stdin instead of just bytes 5..10. Same for Bun.file(fd).slice(...) and spawnSync.

Why

extract_blob in src/runtime/api/bun/spawn/stdio.rs saw a file-backed Blob and converted it directly to Stdio::Fd(store_fd) / Stdio::Path(path) without consulting the Blob's offset/size fields. The child then received a raw fd/path and read the whole file.

Fix

When the Blob's offset != 0 or size != MAX_SIZE (i.e., it's a slice), read the requested byte window into memory via pread and feed it through the normal buffered/memfd pipe path. The whole-file fast path (raw fd/path handed to the child) is unchanged for un-sliced Bun.file(...) and Bun.file(...).slice(0).

For the path-backed case the file is opened O_RDONLY and closed after reading. For the fd-backed case pread is used so the user's fd position is not disturbed.

Tests

Added in test/js/bun/spawn/spawn.test.ts:

  • path-backed Bun.file(path).slice(5, 10)
  • fd-backed Bun.file(fd).slice(5, 10)
  • .slice(0) (whole file — still takes the fd/path fast path)
  • .slice(10, 1000) past EOF (truncates to actual file end)
  • spawnSync with a sliced file

All five fail on main (child receives "0123456789abcdef" instead of "56789"); all pass with this change. Full spawn.test.ts (120 tests) passes; rust:check-all clean on all 10 targets.