Hi,
as the unzip package is not able to unpack split (i.e. foo.zip, foo.z01,
foo.z02 etc.) zip archives, they need to be restored to a single .zip
file via "zip -F <split.zip> --out <combined.zip>" first, after which
<combined.zip> can be extracted via unzip.
However, if the split has been done on a multiple of 16kB and is split
between more than two zipfiles, the restoration fails:
$ dd if=/dev/urandom of=blob bs=1M count=10
10+0 records in
10+0 records out
10485760 bytes (10 MB) copied, 1.00457 s, 10.4 MB/s
$ zip -r -s2m foo.zip blob
adding: blob (deflated 0%)
$ mv blob blob.orig
$ zip -F foo.zip --out tmp.zip
Fix archive (-F) - assume mostly intact archive
copying: blob
$ unzip tmp.zip
Archive: tmp.zip
inflating: blob
error: invalid compressed data to inflate
$ md5sum blob.orig blob
cfbe654be5da3e5ad6104ae47fb62563 blob.orig
dc83002390d9da9936cb21df471db507 blob
The attached test script can be used to easily check different
splitsizes (in kB, note that 64k is the smallest allowed splitsize, the
script does not check the input):
$ splitzip-check.sh 64
Checking with splitsize of 64 kB... Failed!
MD5 of orig: dbc72bd1b1123f90809371644f8c504b
MD5 of test: 80ed7c7d363e2b0e46167e225ef36a37
$ splitzip-check.sh 65
Checking with splitsize of 65 kB... OK!
MD5 of orig: 050ead6ad874654db1b9fccde3511b63
MD5 of test: 050ead6ad874654db1b9fccde3511b63
$ rm -rf zipsplit-check/
We have diagnosed the problem and it is due to a missing check on eof
during a while-loop in bfcopy(). This loop copies the split zips in
chunks of the blocksize, which is 16kB. If the split zip file ends at
exactly that, the next read() returns 0 bytes and as eof is not checked
for, the while loop aborts and subsequently also the copy operation and
finally the check for more .z0* files to copy. This means that only the
first two of potentially many more zipfiles are getting copied,
resulting in a broken combined zipfile.
The attached patch fixes this (also for the "zip -FF" case).
This bug report and the corresponding fix have been commissioned by the
City of Munich's LiMux project.
Michael