Package: zip
Version: 3.0-8
Tags: patch

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

-- 
Michael Banck
Projektleiter / Berater
Tel.: +49 (2161) 4643-171
Fax:  +49 (2161) 4643-100
Email: michael.ba...@credativ.de

credativ GmbH, HRB Mönchengladbach 12080
USt-ID-Nummer: DE204566209
Hohenzollernstr. 133, 41061 Mönchengladbach
Geschäftsführung: Dr. Michael Meskes, Jörg Folz, Sascha Heuer

Attachment: splitzip-check.sh
Description: application/shellscript

--- Begin Message ---
Index: zip-3.0/fileio.c
===================================================================
--- zip-3.0.orig/fileio.c       2014-06-30 13:08:39.114364770 +0200
+++ zip-3.0/fileio.c    2014-06-30 13:20:22.306008671 +0200
@@ -1619,7 +1619,10 @@
 
     if ((k = fread(b, 1, brd, in_file)) == 0)
     {
-      if (fix == 2 && k < brd) {
+      if (feof(in_file) && !ferror(in_file)) {
+        /* do nothing */
+      }
+      else if (fix == 2 && k < brd) {
         free((zvoid *)b);
         return ZE_READ;
       }

--- End Message ---

Reply via email to