diff options
| author | Ondřej Surý <ondrej@sury.org> | 2010-03-09 11:57:54 +0100 |
|---|---|---|
| committer | Ondřej Surý <ondrej@sury.org> | 2010-03-09 11:57:54 +0100 |
| commit | 855a09f4eded707941180c9d90acd17c25e29447 (patch) | |
| tree | a40947efaa9876f31b6ee3956c3f3775768143bb /ext/zip | |
| parent | c852c28a88fccf6e34a2cb091fdfa72bce2b59c7 (diff) | |
| download | php-upstream/5.3.2.tar.gz | |
Imported Upstream version 5.3.2upstream/5.3.2
Diffstat (limited to 'ext/zip')
| -rw-r--r-- | ext/zip/lib/zip_close.c | 9 | ||||
| -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 | 5 | ||||
| -rw-r--r-- | ext/zip/php_zip.c | 10 | ||||
| -rw-r--r-- | ext/zip/php_zip.h | 4 | ||||
| -rw-r--r-- | ext/zip/tests/bug47667.phpt | 3 |
9 files changed, 111 insertions, 66 deletions
diff --git a/ext/zip/lib/zip_close.c b/ext/zip/lib/zip_close.c index bc640c77b..0796f2746 100644 --- a/ext/zip/lib/zip_close.c +++ b/ext/zip/lib/zip_close.c @@ -135,6 +135,7 @@ zip_close(struct zip *za) if ((temp=_zip_create_temp_output(za, &out)) == NULL) { _zip_cdir_free(cd); + free(filelist); return -1; } @@ -192,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; } @@ -264,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; @@ -306,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); @@ -443,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 425f7ff92..39fcb6f62 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 68f92f1fe..b96fd5e48 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 c0b71b861..00a6bdc4e 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 e3840197d..31e12f4fc 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 e7e35e4dd..d72ed144d 100644 --- a/ext/zip/lib/zipint.h +++ b/ext/zip/lib/zipint.h @@ -213,13 +213,14 @@ 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 *); void _zip_dirent_finalize(struct zip_dirent *); void _zip_dirent_init(struct zip_dirent *); -int _zip_dirent_read(struct zip_dirent *, FILE *, - unsigned char **, unsigned int, int, struct zip_error *); +int _zip_dirent_read(struct zip_dirent *, FILE *, unsigned char **, + unsigned int *, int, struct zip_error *); void _zip_dirent_torrent_normalize(struct zip_dirent *); int _zip_dirent_write(struct zip_dirent *, FILE *, int, struct zip_error *); diff --git a/ext/zip/php_zip.c b/ext/zip/php_zip.c index ab2c4e7a7..c2d563fb1 100644 --- a/ext/zip/php_zip.c +++ b/ext/zip/php_zip.c @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2009 The PHP Group | + | Copyright (c) 1997-2010 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_zip.c 276389 2009-02-24 23:55:14Z iliaa $ */ +/* $Id: php_zip.c 294817 2010-02-09 17:51:39Z pajoye $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -182,7 +182,7 @@ static int php_zip_extract_file(struct zip * za, char *dest, char *file, int fil len = spprintf(&file_dirname_fullpath, 0, "%s/%s", dest, file_dirname); } - php_basename(path_cleaned, path_cleaned_len, NULL, 0, &file_basename, (unsigned int *)&file_basename_len TSRMLS_CC); + php_basename(path_cleaned, path_cleaned_len, NULL, 0, &file_basename, (size_t *)&file_basename_len TSRMLS_CC); if (OPENBASEDIR_CHECKPATH(file_dirname_fullpath)) { efree(file_dirname_fullpath); @@ -1637,7 +1637,7 @@ static void php_zip_add_from_pattern(INTERNAL_FUNCTION_PARAMETERS, int type) /* file = Z_STRVAL_PP(zval_file); if (remove_all_path) { php_basename(Z_STRVAL_PP(zval_file), Z_STRLEN_PP(zval_file), NULL, 0, - &basename, (unsigned int *)&file_stripped_len TSRMLS_CC); + &basename, (size_t *)&file_stripped_len TSRMLS_CC); file_stripped = basename; } else if (remove_path && strstr(Z_STRVAL_PP(zval_file), remove_path) != NULL) { file_stripped = Z_STRVAL_PP(zval_file) + remove_path_len + 1; @@ -2674,7 +2674,7 @@ static PHP_MINFO_FUNCTION(zip) php_info_print_table_start(); php_info_print_table_row(2, "Zip", "enabled"); - php_info_print_table_row(2, "Extension Version","$Id: php_zip.c 276389 2009-02-24 23:55:14Z iliaa $"); + php_info_print_table_row(2, "Extension Version","$Id: php_zip.c 294817 2010-02-09 17:51:39Z pajoye $"); php_info_print_table_row(2, "Zip version", PHP_ZIP_VERSION_STRING); php_info_print_table_row(2, "Libzip version", "0.9.0"); diff --git a/ext/zip/php_zip.h b/ext/zip/php_zip.h index e75c11814..92374b00b 100644 --- a/ext/zip/php_zip.h +++ b/ext/zip/php_zip.h @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2009 The PHP Group | + | Copyright (c) 1997-2010 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_zip.h 272370 2008-12-31 11:15:49Z sebastian $ */ +/* $Id: php_zip.h 293036 2010-01-03 09:23:27Z sebastian $ */ #ifndef PHP_ZIP_H #define PHP_ZIP_H diff --git a/ext/zip/tests/bug47667.phpt b/ext/zip/tests/bug47667.phpt index d0a4566f2..cdbf604d8 100644 --- a/ext/zip/tests/bug47667.phpt +++ b/ext/zip/tests/bug47667.phpt @@ -2,7 +2,7 @@ Bug #47667 (ZipArchive::OVERWRITE seems to have no effect) --SKIPIF-- <?php -/* $Id: bug47667.phpt 277253 2009-03-16 10:19:43Z mkoppanen $ */ +/* $Id: bug47667.phpt 294522 2010-02-04 10:09:25Z pajoye $ */ if(!extension_loaded('zip')) die('skip'); ?> --FILE-- @@ -33,6 +33,7 @@ if ($zip->open($filename, ZipArchive::CREATE) !== true) { } echo "files: " , $zip->numFiles; +$zip->close(); unlink($filename); |
