Correctly report ZIP_NOZIP and ZIP_INCONS. Don't flag archives that use data descriptors (size/crc after compressed data) as inconsistent. --HG-- branch : HEAD
diff --git a/lib/zip_open.c b/lib/zip_open.c index cd5b970..16f25c3 100644 --- a/lib/zip_open.c +++ b/lib/zip_open.c
@@ -1,5 +1,5 @@ /* - $NiH: zip_open.c,v 1.37 2006/04/23 18:47:34 dillo Exp $ + $NiH: zip_open.c,v 1.38 2006/05/04 00:01:26 dillo Exp $ zip_open.c -- open zip archive Copyright (C) 1999-2006 Dieter Baron and Thomas Klausner @@ -132,22 +132,19 @@ return NULL; } - best = -2; + best = -1; cdir = NULL; match = buf; + _zip_error_set(&err2, ZIP_ER_NOZIP, 0); + while ((match=_zip_memmem(match, buflen-(match-buf)-18, (const unsigned char *)EOCD_MAGIC, 4))!=NULL) { /* found match -- check, if good */ /* to avoid finding the same match all over again */ match++; if ((cdirnew=_zip_readcdir(fp, buf, match-1, buflen, flags, - &err2)) == NULL) { - if (best == -2) { - set_error(zep, &err2, 0); - best = -1; - } + &err2)) == NULL) continue; - } if (cdir) { if (best <= 0) @@ -174,11 +171,7 @@ free(buf); if (best < 0) { - /* no consistent eocd found */ - if (best == -2) { - /* no eocd found at all */ - set_error(zep, NULL, ZIP_ER_NOZIP); - } + set_error(zep, &err2, 0); _zip_cdir_free(cdir); fclose(fp); return NULL; @@ -378,7 +371,7 @@ return -1; if (_zip_headercomp(cd->entry+i, 0, &temp, 1) != 0) { - _zip_error_set(error, ZIP_ER_NOZIP, 0); + _zip_error_set(error, ZIP_ER_INCONS, 0); _zip_dirent_finalize(&temp); return -1; } @@ -407,14 +400,32 @@ #endif || (h1->comp_method != h2->comp_method) || (h1->last_mod != h2->last_mod) - || (h1->crc != h2->crc) - || (h1->comp_size != h2->comp_size) - || (h1->uncomp_size != h2->uncomp_size) || (h1->filename_len != h2->filename_len) || !h1->filename || !h2->filename || strcmp(h1->filename, h2->filename)) return -1; + /* check that CRC and sizes are zero if data descriptor is used */ + if ((h1->bitflags & ZIP_GPBF_DATA_DESCRIPTOR) && local1p + && (h1->crc != 0 + || h1->comp_size != 0 + || h1->uncomp_size != 0)) + return -1; + if ((h2->bitflags & ZIP_GPBF_DATA_DESCRIPTOR) && local2p + && (h2->crc != 0 + || h2->comp_size != 0 + || h2->uncomp_size != 0)) + return -1; + + /* check that CRC and sizes are equal if no data descriptor is used */ + if (((h1->bitflags & ZIP_GPBF_DATA_DESCRIPTOR) == 0 || local1p == 0) + && ((h2->bitflags & ZIP_GPBF_DATA_DESCRIPTOR) == 0 || local2p == 0)) { + if ((h1->crc != h2->crc) + || (h1->comp_size != h2->comp_size) + || (h1->uncomp_size != h2->uncomp_size)) + return -1; + } + if ((local1p == local2p) && ((h1->extrafield_len != h2->extrafield_len) || (h1->extrafield_len && h2->extrafield
diff --git a/lib/zipint.h b/lib/zipint.h index ed665d7..cc01016 100644 --- a/lib/zipint.h +++ b/lib/zipint.h
@@ -2,7 +2,7 @@ #define _HAD_ZIPINT_H /* - $NiH: zipint.h,v 1.47 2006/04/23 00:40:48 wiz Exp $ + $NiH: zipint.h,v 1.48 2006/04/24 14:04:19 dillo Exp $ zipint.h -- internal declarations. Copyright (C) 1999, 2003, 2004, 2005, 2006 Dieter Baron and Thomas Klausner @@ -79,6 +79,7 @@ /* directory entry: general purpose bit flags */ #define ZIP_GPBF_ENCRYPTED 0x0001 /* is encrypted */ +#define ZIP_GPBF_DATA_DESCRIPTOR 0x0008 /* crc/size after file data */ #define ZIP_GPBF_STRONG_ENCRYPTION 0x0040 /* uses strong encryption */ /* error information */