mirror of
https://github.com/nodejs/node.git
synced 2026-11-09 15:11:11 -05:00
A file descriptor obtained on a mounted path answers several `node:fs`
calls differently from one on a real file, in both providers:
* `writeFileSync(path, data, { flag: 'r+' })` replaces the whole file
instead of overwriting bytes from offset 0 and keeping the tail.
* Numeric open flags are mapped by treating any write-ish bit as "w":
`O_WRONLY` alone truncates, and `O_RDONLY | O_CREAT` opens the file
write-only and truncates it.
* A handle opened with "a+" starts its read offset at the end of the
file, so the first read returns nothing; O_APPEND only affects writes.
The ZipProvider handle additionally:
* throws EISDIR instead of EBADF when reading a write-only handle or
writing a read-only one;
* leaves stale bytes in place when `ftruncate` grows a file that was
previously shrunk, where real files read back as zeros;
* rejects a BigInt `position` with a TypeError from mixing number and
BigInt arithmetic.
This adds a test that runs the same sequence of calls against a memory
mount and a ZIP mount and expects the real-fs result, so every
divergence shows up as its own failing case.
Proposed solution: decode numeric flags bit by bit (O_TRUNC decides
truncation, O_CREAT decides creation, O_WRONLY/O_RDWR decide access)
instead of collapsing them to a flag string; keep the read offset at 0
for append handles and only force writes to the end; make the handle
`writeFile` for non-truncating flags write at offset 0 without
shrinking; in the ZIP handle use EBADF for access-mode violations,
zero-fill on growth in `#doTruncate`, and coerce `position` with
`Number()` as the memory handle does.
Signed-off-by: Philipp Dunkel <pip@pipobscure.com>
PR-URL: https://github.com/nodejs/node/pull/65854
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>