Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix zip files created on Windows being unusable on Linux/MacOS (missing executable bits on directories) #59

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

Jimbly
Copy link

@Jimbly Jimbly commented May 10, 2020

If a caller passes in a mode on the addEmptyDirectory() call, and that mode is taken directly from the (albeit platform-specific) fs.stat()'s mode, we end up creating zip files with directories that do not have the executable bit, which makes them completely unopenable on some platforms (MacOS Finder), and creates bad directory entries on others (Linux).

I also couldn't help but fix setFileAttributesMode to always set either S_IFDIR or S_IFREG, since it seemed really weird that it was only sometimes setting it (only if mode === null). This isn't to fix any observed bug, so I'd be perfectly fine sending a PR without that part of the change if needed for some reason, but I'm guessing all zip clients ignore those two flags anyway, so it probably doesn't matter ^_^.

This would resolve the following issues:
sindresorhus/gulp-zip#76
sindresorhus/gulp-zip#106
sindresorhus/gulp-zip#112

Some discussion about trying to work around it at a higher level here: sindresorhus/gulp-zip#117 . Ending conclusion was that there's probably no reasonable situation in which we would want yazl to be creating zip files that cannot be opened on some platforms, so if it's writing platform-specific mode bits, it makes sense to massage them to be portable.

@@ -92,6 +92,14 @@ var BufferList = require("bl");
if (entry.fileName !== expectedName) {
throw new Error("unexpected entry fileName: " + entry.fileName + ", expected: " + expectedName);
}
var mode = entry.externalFileAttributes >>> 16;
if (/\/$/.test(entry.fileName)) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (/\/$/.test(entry.fileName)) {
if (entry.fileName.startsWith('/')) {

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The other spot in this file is using that regex to decide if it's a directory, so just matching that style, though I agree it's not particularly readable. So much so that your suggestion is actually backwards (should be fileName.endsWith('/')) ^_^. endsWith, however, is ES6+ only, and doesn't exist in Node v0.10, that this library is still being tested against.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants