javanthropus / archive-zip

A simple Ruby-esque interface to creating, extracting, and updating ZIP archives in 100% Ruby.
https://rubygems.org/gems/archive-zip
MIT License
83 stars 10 forks source link

ArgumentError: second must not be greater than 29 on valid zip files #19

Open aniruddhaborah opened 6 years ago

aniruddhaborah commented 6 years ago

Hi I'm getting the above error for zip files, that can be unzipped normally using command line tools.

Just as an aside, I'm curious why seconds can not be greater than 29 whereas all the other time measurements seem to follow their corresponding max values, 59 for minutes, 24 for hours etc

javanthropus commented 6 years ago

This is a limitation of the DOS time stamps. As I understood the spec when I originally read it, the seconds field of the structure really only counts every other second in order to conserve 1 bit in the structure. That maximum value of 29 actually corresponds second 58 in the minute, a value of 15 is second 30, and so on.

While a larger value can be set in that structure, it's technically invalid since it would mean you're counting second 60 or more of a minute, which is nonsensical. In order to loosen the restriction imposed by this library, a new decision would have to be made regarding how to handle these excessively large values of seconds. The current decision is to error out, but it's also possible to cap excessive values to the maximum valid value. Probably the thing to do would be to allow support for sloppy zip files when specifically requested.

javanthropus commented 6 years ago

@aniruddhaborah, can you tell me more about how you ended up with ZIP files that contain invalid time stamps?

aniruddhaborah commented 6 years ago

The zip files were created on iOS using https://github.com/pixelglow/ZipZap A small percentage of zip files end up with these timestamps

javanthropus commented 6 years ago

I believe the disagreement with ZipZap is in the method of conversion for seconds:

https://github.com/pixelglow/ZipZap/blob/d591ce37c9b51873926fdf87de728415223d57b2/ZipZap/ZZNewArchiveEntryWriter.mm#L118

Specifically, ZipZap increments the count of full resolution seconds by 1 prior to encoding it into the structure. This means that if the full resolution seconds is 59, ZipZap will encode that into the ZIP file as 60 seconds as far is this project is concerned, which is the nonsensical value I mentioned before. ZipZap also can't represent 0 seconds with this method of encoding.

aniruddhaborah commented 6 years ago

Any plans to add support to skip the time validations for these zip files?

javanthropus commented 6 years ago

What does InfoZip's unzip tool do with respect to those invalid time stamps? Does it set the seconds to 0 or 59, or does it do something else? Much of the logic in this library was built using the unzip tool as a reference, so I would be willing to make it follow the behavior of that tool here.