diff options
author | Pierre Joye <pajoye@php.net> | 2010-02-01 20:56:03 +0000 |
---|---|---|
committer | Pierre Joye <pajoye@php.net> | 2010-02-01 20:56:03 +0000 |
commit | 3ef47217d7b96a92de3497859f246b6de04681e8 (patch) | |
tree | b079a7be47aeeace142ae29d9d24b53675fa9529 /ext/zip | |
parent | fa197ab9cc2ebc6c47bb26299cc5a0035e0b772f (diff) | |
download | php-git-3ef47217d7b96a92de3497859f246b6de04681e8.tar.gz |
- update to 0.9.3
Diffstat (limited to 'ext/zip')
-rw-r--r-- | ext/zip/lib/zip_close.c | 8 | ||||
-rw-r--r-- | ext/zip/lib/zip_dirent.c | 94 | ||||
-rw-r--r-- | ext/zip/lib/zip_file_get_offset.c | 2 | ||||
-rw-r--r-- | ext/zip/lib/zip_fread.c | 29 | ||||
-rw-r--r-- | ext/zip/lib/zip_open.c | 21 | ||||
-rw-r--r-- | ext/zip/lib/zipint.h | 1 |
6 files changed, 99 insertions, 56 deletions
diff --git a/ext/zip/lib/zip_close.c b/ext/zip/lib/zip_close.c index 982ee855f2..0796f27462 100644 --- a/ext/zip/lib/zip_close.c +++ b/ext/zip/lib/zip_close.c @@ -193,7 +193,8 @@ zip_close(struct zip *za) error = 1; break; } - if (_zip_dirent_read(&de, za->zp, NULL, 0, 1, &za->error) != 0) { + if (_zip_dirent_read(&de, za->zp, NULL, NULL, 1, + &za->error) != 0) { error = 1; break; } @@ -265,6 +266,8 @@ zip_close(struct zip *za) _zip_dirent_finalize(&de); } + free(filelist); + if (!error) { if (write_cdir(za, cd, out) < 0) error = 1; @@ -307,6 +310,8 @@ zip_close(struct zip *za) mask = umask(0); umask(mask); chmod(za->zn, 0666&~mask); + if (za->ch_comment) + free(za->ch_comment); _zip_free(za); free(temp); @@ -444,6 +449,7 @@ add_data_uncomp(struct zip *za, zip_source_callback cb, void *ud, zstr.next_out = (Bytef *)b2; zstr.avail_out = sizeof(b2); + zstr.next_in = NULL; zstr.avail_in = 0; flush = 0; diff --git a/ext/zip/lib/zip_dirent.c b/ext/zip/lib/zip_dirent.c index 425f7ff922..39fcb6f62d 100644 --- a/ext/zip/lib/zip_dirent.c +++ b/ext/zip/lib/zip_dirent.c @@ -68,6 +68,30 @@ _zip_cdir_free(struct zip_cdir *cd) +int +_zip_cdir_grow(struct zip_cdir *cd, int nentry, struct zip_error *error) +{ + struct zip_dirent *entry; + + if (nentry < cd->nentry) { + _zip_error_set(error, ZIP_ER_INTERNAL, 0); + return -1; + } + + if ((entry=((struct zip_dirent *) + realloc(cd->entry, sizeof(*(cd->entry))*nentry))) == NULL) { + _zip_error_set(error, ZIP_ER_MEMORY, 0); + return -1; + } + + cd->nentry = nentry; + cd->entry = entry; + + return 0; +} + + + struct zip_cdir * _zip_cdir_new(int nentry, struct zip_error *error) { @@ -173,19 +197,23 @@ _zip_dirent_init(struct zip_dirent *de) Fills the zip directory entry zde. If bufp is non-NULL, data is taken from there and bufp is advanced - by the amount of data used; no more than left bytes are used. - Otherwise data is read from fp as needed. + by the amount of data used; otherwise data is read from fp as needed. + + if leftp is non-NULL, no more bytes than specified by it are used, + and *leftp is reduced by the number of bytes used. - If localp != 0, it reads a local header instead of a central + If local != 0, it reads a local header instead of a central directory entry. Returns 0 if successful. On error, error is filled in and -1 is returned. + + XXX: leftp and file position undefined on error. */ int _zip_dirent_read(struct zip_dirent *zde, FILE *fp, - unsigned char **bufp, unsigned int left, int localp, + unsigned char **bufp, unsigned int *leftp, int local, struct zip_error *error) { unsigned char buf[CDENTRYSIZE]; @@ -193,18 +221,19 @@ _zip_dirent_read(struct zip_dirent *zde, FILE *fp, unsigned short dostime, dosdate; unsigned int size; - if (localp) + if (local) size = LENTRYSIZE; else size = CDENTRYSIZE; - + + if (leftp && (*leftp < size)) { + _zip_error_set(error, ZIP_ER_NOZIP, 0); + return -1; + } + if (bufp) { /* use data from buffer */ cur = *bufp; - if (left < size) { - _zip_error_set(error, ZIP_ER_NOZIP, 0); - return -1; - } } else { /* read entry from disk */ @@ -212,11 +241,10 @@ _zip_dirent_read(struct zip_dirent *zde, FILE *fp, _zip_error_set(error, ZIP_ER_READ, errno); return -1; } - left = size; cur = buf; } - if (memcmp(cur, (localp ? LOCAL_MAGIC : CENTRAL_MAGIC), 4) != 0) { + if (memcmp(cur, (local ? LOCAL_MAGIC : CENTRAL_MAGIC), 4) != 0) { _zip_error_set(error, ZIP_ER_NOZIP, 0); return -1; } @@ -225,7 +253,7 @@ _zip_dirent_read(struct zip_dirent *zde, FILE *fp, /* convert buffercontents to zip_dirent */ - if (!localp) + if (!local) zde->version_madeby = _zip_read2(&cur); else zde->version_madeby = 0; @@ -245,7 +273,7 @@ _zip_dirent_read(struct zip_dirent *zde, FILE *fp, zde->filename_len = _zip_read2(&cur); zde->extrafield_len = _zip_read2(&cur); - if (localp) { + if (local) { zde->comment_len = 0; zde->disk_number = 0; zde->int_attrib = 0; @@ -263,13 +291,14 @@ _zip_dirent_read(struct zip_dirent *zde, FILE *fp, zde->extrafield = NULL; zde->comment = NULL; - if (bufp) { - if (left < CDENTRYSIZE + (zde->filename_len+zde->extrafield_len - +zde->comment_len)) { - _zip_error_set(error, ZIP_ER_NOZIP, 0); - return -1; - } + size += zde->filename_len+zde->extrafield_len+zde->comment_len; + if (leftp && (*leftp < size)) { + _zip_error_set(error, ZIP_ER_NOZIP, 0); + return -1; + } + + if (bufp) { if (zde->filename_len) { zde->filename = _zip_readstr(&cur, zde->filename_len, 1, error); if (!zde->filename) @@ -312,6 +341,8 @@ _zip_dirent_read(struct zip_dirent *zde, FILE *fp, if (bufp) *bufp = cur; + if (leftp) + *leftp -= size; return 0; } @@ -442,23 +473,22 @@ _zip_dirent_write(struct zip_dirent *zde, FILE *fp, int localp, static time_t _zip_d2u_time(int dtime, int ddate) { - struct tm *tm; - time_t now; + struct tm tm; - now = time(NULL); - tm = localtime(&now); + memset(&tm, sizeof(tm), 0); + /* let mktime decide if DST is in effect */ - tm->tm_isdst = -1; + tm.tm_isdst = -1; - tm->tm_year = ((ddate>>9)&127) + 1980 - 1900; - tm->tm_mon = ((ddate>>5)&15) - 1; - tm->tm_mday = ddate&31; + tm.tm_year = ((ddate>>9)&127) + 1980 - 1900; + tm.tm_mon = ((ddate>>5)&15) - 1; + tm.tm_mday = ddate&31; - tm->tm_hour = (dtime>>11)&31; - tm->tm_min = (dtime>>5)&63; - tm->tm_sec = (dtime<<1)&62; + tm.tm_hour = (dtime>>11)&31; + tm.tm_min = (dtime>>5)&63; + tm.tm_sec = (dtime<<1)&62; - return mktime(tm); + return mktime(&tm); } diff --git a/ext/zip/lib/zip_file_get_offset.c b/ext/zip/lib/zip_file_get_offset.c index 68f92f1fe6..b96fd5e480 100644 --- a/ext/zip/lib/zip_file_get_offset.c +++ b/ext/zip/lib/zip_file_get_offset.c @@ -63,7 +63,7 @@ _zip_file_get_offset(struct zip *za, int idx) return 0; } - if (_zip_dirent_read(&de, za->zp, NULL, 0, 1, &za->error) != 0) + if (_zip_dirent_read(&de, za->zp, NULL, NULL, 1, &za->error) != 0) return 0; offset += LENTRYSIZE + de.filename_len + de.extrafield_len; diff --git a/ext/zip/lib/zip_fread.c b/ext/zip/lib/zip_fread.c index c0b71b8619..00a6bdc4e0 100644 --- a/ext/zip/lib/zip_fread.c +++ b/ext/zip/lib/zip_fread.c @@ -63,7 +63,7 @@ zip_fread(struct zip_file *zf, void *outbuf, size_t toread) } return 0; } - + if ((zf->flags & ZIP_ZF_DECOMP) == 0) { ret = _zip_file_fillbuf(outbuf, toread, zf); if (ret > 0) { @@ -84,25 +84,22 @@ zip_fread(struct zip_file *zf, void *outbuf, size_t toread) switch (ret) { case Z_STREAM_END: - zf->flags |= ZIP_ZF_EOF; + if (zf->zstr->total_out == out_before) { + if (zf->crc != zf->crc_orig) { + _zip_error_set(&zf->error, ZIP_ER_CRC, 0); + return -1; + } + else + return 0; + } - case Z_OK: + /* fallthrough */ - /* all ok */ - /* Z_STREAM_END probably won't happen, since we didn't - have a header */ + case Z_OK: len = zf->zstr->total_out - out_before; if (len >= zf->bytes_left || len >= toread) { - if (zf->flags & ZIP_ZF_CRC) { - zf->crc = crc32(zf->crc, (Bytef *)outbuf, len); - if (zf->flags & ZIP_ZF_EOF == 1) { - if (zf->crc != zf->crc_orig) { - _zip_error_set(&zf->error, ZIP_ER_CRC, 0); - return -1; - } - - } - } + if (zf->flags & ZIP_ZF_CRC) + zf->crc = crc32(zf->crc, (Bytef *)outbuf, len); zf->bytes_left -= len; return len; } diff --git a/ext/zip/lib/zip_open.c b/ext/zip/lib/zip_open.c index e3840197dd..31e12f4fc5 100644 --- a/ext/zip/lib/zip_open.c +++ b/ext/zip/lib/zip_open.c @@ -162,6 +162,7 @@ _zip_readcdir(FILE *fp, unsigned char *buf, unsigned char *eocd, int buflen, struct zip_cdir *cd; unsigned char *cdp, **bufp; int i, comlen, nentry; + unsigned int left; comlen = buf + buflen - eocd - EOCDLEN; if (comlen < 0) { @@ -215,7 +216,6 @@ _zip_readcdir(FILE *fp, unsigned char *buf, unsigned char *eocd, int buflen, } } - cdp = eocd; if (cd->size < (unsigned int)(eocd-buf)) { /* if buffer already read in, use it */ cdp = eocd - cd->size; @@ -239,14 +239,23 @@ _zip_readcdir(FILE *fp, unsigned char *buf, unsigned char *eocd, int buflen, } } - for (i=0; i<cd->nentry; i++) { - if ((_zip_dirent_read(cd->entry+i, fp, bufp, eocd-cdp, 0, - error)) < 0) { + left = cd->size; + i=0; + do { + if (i == cd->nentry && left > 0) { + /* Infozip extension for more than 64k entries: + nentries wraps around, size indicates correct EOCD */ + _zip_cdir_grow(cd, cd->nentry+0x10000, error); + } + + if ((_zip_dirent_read(cd->entry+i, fp, bufp, &left, 0, error)) < 0) { cd->nentry = i; _zip_cdir_free(cd); return NULL; } - } + i++; + + } while (i<cd->nentry); return cd; } @@ -295,7 +304,7 @@ _zip_checkcons(FILE *fp, struct zip_cdir *cd, struct zip_error *error) return -1; } - if (_zip_dirent_read(&temp, fp, NULL, 0, 1, error) == -1) + if (_zip_dirent_read(&temp, fp, NULL, NULL, 1, error) == -1) return -1; if (_zip_headercomp(cd->entry+i, 0, &temp, 1) != 0) { diff --git a/ext/zip/lib/zipint.h b/ext/zip/lib/zipint.h index e7e35e4dd7..f1514c5b6a 100644 --- a/ext/zip/lib/zipint.h +++ b/ext/zip/lib/zipint.h @@ -213,6 +213,7 @@ extern const int _zip_err_type[]; int _zip_cdir_compute_crc(struct zip *, uLong *); void _zip_cdir_free(struct zip_cdir *); +int _zip_cdir_grow(struct zip_cdir *, int, struct zip_error *); struct zip_cdir *_zip_cdir_new(int, struct zip_error *); int _zip_cdir_write(struct zip_cdir *, FILE *, struct zip_error *); |