Skip to content

vfs: validate directory renames in ZipProvider - #66976

Open
alanprado1 wants to merge 2 commits into
nodejs:mainfrom
alanprado1:vfs-zip-provider-rename-validation
Open

alanprado1 wants to merge 2 commits into
nodejs:mainfrom
alanprado1:vfs-zip-provider-rename-validation

Conversation

@alanprado1

Copy link
Copy Markdown

ZipProvider.rename() / renameSync() never inspected the destination when renaming a directory, so:

  • a directory could be merged into a non-empty directory, silently overwriting its files (should be ENOTEMPTY);
  • a directory could be renamed onto a regular file, leaving entries beneath a file (should be ENOTDIR);
  • members were read and written one at a time, so a member failing its CRC check left the earlier ones already written, which a writable ZipFile persists to disk.

This adds a destination check for directory renames (ENOTDIR / ENOTEMPTY, matching rename(2) and the default provider's behaviour in test-vfs-rename.js) and reads every member before writing any.

test-vfs-rename.js already asserts both errors, but only against the default provider, which is why this wasn't caught. The new test-vfs-zip-provider-rename.js covers all cases through both the sync and promise APIs, over ZipBuffer and a reopened writable ZipFile.

Not covered: a write failure partway through (e.g. an I/O error) can still leave a partial rename; that would need rollback and is left for a follow-up.

Thanks to @aron-intframe for the root-cause analysis in the issue.

Fixes: #66972

ZipProvider.rename() and renameSync() never inspected the destination
when renaming a directory, so a directory could be merged into a
non-empty directory (silently overwriting its files) or placed beneath
an existing regular file. Reject both cases with ENOTEMPTY and ENOTDIR,
matching rename(2) and the default provider.

Directory renames also interleaved reading and writing members, so a
member that failed to read (e.g. a CRC mismatch) left the members
before it already written to the archive, which a writable ZipFile
persists to disk. Read every member before writing any.

Fixes: nodejs#66972
@nodejs-github-bot nodejs-github-bot added needs-ci PRs that need a full CI run. vfs Issues and PRs related to the virtual filesystem subsystem. labels Oct 24, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Welcome to Node.js, and thank you for your first contribution!

Before review, please take a moment to read:

Please make sure every commit is signed off. For a first pull request, GitHub Actions require collaborator approval and Jenkins CI must be started by a collaborator or triager, so an initial wait is normal.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs-ci PRs that need a full CI run. vfs Issues and PRs related to the virtual filesystem subsystem.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

vfs: ZipProvider.rename() overwrites nonempty directories and persists partial modifications after failure

2 participants