From: Pierre Joye Date: Tue, 11 Aug 2009 15:12:00 +0000 (+0000) Subject: - fixed bug #49072, feof never returns true for damaged file in zip X-Git-Tag: php-5.2.11RC1~10 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a212a1641975b45dd52f5ca7f780a0a1874ad396;p=php - fixed bug #49072, feof never returns true for damaged file in zip --- diff --git a/NEWS b/NEWS index 8d6a0fc65a..161ca05c15 100644 --- a/NEWS +++ b/NEWS @@ -11,6 +11,7 @@ PHP NEWS - Fixed bug #49095 (proc_get_status['exitcode'] fails on win32). (Felipe) - Fixed bug #49074 (private class static fields can be modified by using reflection). (Jani) +- Fixed bug #49072 (feof never returns true for damaged file in zip). (Pierre) - Fixed bug #49052 (context option headers freed too early when using --with-curlwrappers). (Jani) - Fixed bug #49032 (SplFileObject::fscanf() variables passed by reference). diff --git a/ext/zip/lib/zip_fread.c b/ext/zip/lib/zip_fread.c index 1a2b0e3816..861c865c8a 100644 --- a/ext/zip/lib/zip_fread.c +++ b/ext/zip/lib/zip_fread.c @@ -83,15 +83,26 @@ zip_fread(struct zip_file *zf, void *outbuf, size_t toread) ret = inflate(zf->zstr, Z_SYNC_FLUSH); switch (ret) { - case Z_OK: case Z_STREAM_END: + zf->flags |= ZIP_ZF_EOF; + + case Z_OK: + /* all ok */ /* Z_STREAM_END probably won't happen, since we didn't have a header */ 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_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; + } + + } + } zf->bytes_left -= len; return len; } diff --git a/ext/zip/tests/bug49072.phpt b/ext/zip/tests/bug49072.phpt new file mode 100644 index 0000000000..04bd06e4ad --- /dev/null +++ b/ext/zip/tests/bug49072.phpt @@ -0,0 +1,24 @@ +--TEST-- +Bug #49072 (feof never returns true for damaged file in zip) +--SKIPIF-- + +--FILE-- +open($f, ZipArchive::CHECKCONS)) { + exit ('error can\'t open'); +} +$r = $o->getStream('file1'); // this file has a wrong crc +if (!$r)die('failed to open a stream for file1'); +$s = ''; +while (! feof($r)) { + $s .= fread($r,1024); +} +?> +--EXPECTF-- + +Warning: fread(): Zip stream error: CRC error in %s on line %d diff --git a/ext/zip/tests/bug49072.zip b/ext/zip/tests/bug49072.zip new file mode 100644 index 0000000000..16bbcd011b Binary files /dev/null and b/ext/zip/tests/bug49072.zip differ diff --git a/ext/zip/zip_stream.c b/ext/zip/zip_stream.c index 1f305509ea..202e2a44f5 100644 --- a/ext/zip/zip_stream.c +++ b/ext/zip/zip_stream.c @@ -35,8 +35,14 @@ static size_t php_zip_ops_read(php_stream *stream, char *buf, size_t count TSRML if (self->za && self->zf) { n = (size_t)zip_fread(self->zf, buf, (int)count); - - if (n == 0) { + if (n < 0) { + int ze, se; + zip_file_error_get(self->zf, &ze, &se); + stream->eof = 1; + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Zip stream error: %s", zip_file_strerror(self->zf)); + return 0; + } + if (n == 0 || n < count) { stream->eof = 1; } else { self->cursor += n;