create files with a literal `/` in the name #130

Closed
SheetJSDev opened this Issue May 13, 2014 · 9 comments

Projects

None yet

3 participants

@SheetJSDev
Contributor

OPC requires file names like "foo/bar", but jszip seems to interpret those as folder names:

zip.file('foo/bar', 'baz');
zip.folder('foo').file('bar', 'baz') // equivalent

All of the checks seem to directly look for a slash character. Ideally something like "foo//bar" or "foo/bar" or some other expression would allow for a literal slash in the name

@dduponchel
Collaborator

zip.file('foo/bar', 'baz'); will creates 2 entries (in memory and when generating a zip file) : foo/ (no content, marked as directory) and foo/bar (with content). Do you have an example of what you're trying to generate ?

@SheetJSDev
Contributor

@dduponchel Take a peek at https://github.com/sheetjs/test_files/blob/master/AutoFilter.xlsx?raw=true (generated by Excel 2011) and note that directory entries do not show up (at least, according to zip.vim). This is true of zip files from 2007, 2010, 2011, and 2013.

The quote which led me to conclude that Excel wasn't generating individual folders comes from ECMA376 Part II (Open Packaging Conventions) Section 9 (Package Model) Subsection 9.1.1 (Part Names):

The part name "/hello/world/doc.xml" contains three segments: "hello", "world", and "doc.xml" ... Note that segments are not explicitly represented as folders in the package model, and no directory of folders exists in the package model

@dduponchel
Collaborator

Indeed, Excel doesn't generate sub folders. The change itself is small : we just need a condition on this folderAdd call (and maybe one on remove() to have a consistent behavior and remove individual entries).
I don't think that a special syntax is a good idea. We could add an options object on the JSZip instance (and the default values on the JSZip object) and a boolean value for this behavior.

@SheetJSDev
Contributor

@dduponchel alternatively you could disable the magic folder-creation behavior entirely (and require people to explicitly create the folder first).

@dduponchel
Collaborator

We could. I tested with some programs (unzip, 7z, the default zip program in windows XP and windows 7) with a zip file with "missing" folders and they all create sub folders when necessary.
But there are a lot of software reading zip files (archive managers, xlsx readers, epub readers, etc) and I can't predict if the result with a zip file with and without extra folder entries. What's your experience with xlsx readers and extra folders ?

@SheetJSDev
Contributor

Numbers for iOS is showing some strange behavior. Writing the paths in a different order seems to confuse the parser only if the directory entries show up after the [Content_Types].xml subfile. However, reworking the order of writing does seem to resolve the issue.

Food for thought: other JS zip implementations (for example, https://www.npmjs.org/package/archiver) and implementations in other languages (https://rubygems.org/gems/rubyzip) don't create those directory entries.

@Mithgol
Contributor
Mithgol commented May 15, 2014

Wait, what does “don't create those directory entries” mean exactly? “Don't create directory entries that are files with / in names”? Or “don't make zip entries that are automatically created directories”?

@SheetJSDev
Contributor

@Mithgol consider this script:

var JSZip = require('jszip');
var fs = require('fs');
var data = fs.readFileSync('old.zip');
var zip = new JSZip(data);
fs.writeFileSync('new.zip', zip.generate({type:'nodebuffer'}));

All it does is parse old.zip and save as new.zip.

Now run this and take a peek at what zip.vim reports:

vim -d old.zip new.zip

I'm not sure why, but those extra directory entries are confusing some readers.

@dduponchel
Collaborator

I've tested some archive managers (windows 7 "compressed folders", winzip, winrar, 7zip, izarc) on this :

  • they all support my two test zips (with and without folders)
  • izarc and winrar have an option to remove them at creation time
  • 7zip, winrar and winzip create sub folders
  • izarc does not
  • windows does sometimes (it seems to skip the first levels)

I've also checked the java API, which doesn't create sub folders.

It seems that changing the default behavior shouldn't break anything.

@dduponchel dduponchel added a commit that closed this issue May 29, 2014
@dduponchel dduponchel Don't generate subfolders.
Fix #130, see this issue for more informations.
5c91113
@de-code de-code pushed a commit to de-code/gulp-zip that referenced this issue Jul 24, 2014
de include folder structure in zip file by using jszip's folder function
(this was broken due to Stuk/jszip#130)
51ab3ea
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment