archiverjs / node-archiver

a streaming interface for archive generation
https://www.archiverjs.com
MIT License
2.76k stars 218 forks source link

Cannot add file named `\` #743

Open nwalters512 opened 4 months ago

nwalters512 commented 4 months ago

Consider the following code:

const archiver = require('archiver');

const archive = archiver('zip');

archive.append('hello, world!', { name: '\\' });

This is meant to add a file named \ to the archive. According to the specification (https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT), this should be allowed, and it's certainly allowed by standard implementations of the zip command (that is, touch '\' && zip -r test.zip '\' works as expected and produces an archive containing a single file \).

However, what happens in practice is that this fails with the following error message:

ArchiverError: entry name must be a non-empty string value

This happens because of the following line:

https://github.com/archiverjs/node-archiver/blob/2050cfacc06dbc9a1c5acc67ce7b41ff230990a6/lib/core.js#L310

Which in turn runs this:

https://github.com/archiverjs/archiver-utils/blob/695387cdc4816a3d19edb6f1d5473e6395479567/index.js#L91-L93

sanitizePath transforms \ into the empty string.

The same underlying problem causes a different issue with the following code:

archive.append('hello, world!', { name: 'testing/\\' });

In this case, the name is transformed to testing/, which incorrectly results in the creation of a directory instead of a file with the specified contents.

One more example:

archive.append('hello, world!', { name: 'testing/foo\\bar.txt' });

This actually creates testing/foo/bar.txt, which is not at all what was intended.

ctalkington commented 4 months ago

I think some of those concerns came from cross OS pathing issues. does the \ file actually extract on say windows? or is it unaccessible?

nwalters512 commented 4 months ago

Unfortunately I don't have access to a Windows machine to test it on. I imagine the behavior could vary between different tools on Windows.