From 566f8b136a85568e3f59250c2d6c3377e30870b3 Mon Sep 17 00:00:00 2001 From: Marcus Boerger Date: Thu, 12 Jan 2006 02:33:28 +0000 Subject: [PATCH] - Use consumed filter to check number of compressed bytes read # This fixes all tests again --- ext/phar/phar.c | 21 ++++++++++++++++----- ext/phar/tests/015.phpt | 2 +- ext/phar/tests/016.phpt | 30 +++++++++++++++++++++++------- ext/phar/tests/016b.phpt | 4 ++-- 4 files changed, 42 insertions(+), 15 deletions(-) diff --git a/ext/phar/phar.c b/ext/phar/phar.c index 007e713496..ca7c0b530d 100644 --- a/ext/phar/phar.c +++ b/ext/phar/phar.c @@ -689,7 +689,7 @@ static php_stream * php_stream_phar_url_wrapper(php_stream_wrapper *wrapper, cha char tmpbuf[8]; php_url *resource = NULL; php_stream *fp, *fpf; - php_stream_filter *filter; + php_stream_filter *filter, *consumed; php_uint32 offset; resource = php_url_parse(path); @@ -780,6 +780,12 @@ static php_stream * php_stream_phar_url_wrapper(php_stream_wrapper *wrapper, cha efree(internal_file); return NULL; } + /* Nnfortunatley we cannot check the read position of fp after getting */ + /* uncompressed data because the new stream posiition is being changed */ + /* by the number of bytes read throughthe filter not by the raw number */ + /* bytes being consumed on the stream. Therefor use a consumed filter. */ + consumed = php_stream_filter_create("consumed", NULL, php_stream_is_persistent(fp) TSRMLS_CC); + php_stream_filter_append(&fp->readfilters, consumed); php_stream_filter_append(&fp->readfilters, filter); idata->fp = php_stream_temp_new(); @@ -792,10 +798,15 @@ static php_stream * php_stream_phar_url_wrapper(php_stream_wrapper *wrapper, cha } php_stream_filter_flush(filter, 1); php_stream_filter_remove(filter, 1 TSRMLS_CC); - /* Nnfortunatley we cannot check the read position of fp after getting */ - /* uncompressed data because the new stream posiition is being changed */ - /* by the number of bytes read throughthe filter not by the raw number */ - /* bytes being consumed on the stream. Correct the stream pos anyway. */ + php_stream_filter_flush(consumed, 1); + php_stream_filter_remove(consumed, 1 TSRMLS_CC); + if (offset + idata->internal_file->compressed_filesize != php_stream_tell(fp)) { + php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: internal corruption of phar \"%s\" (actual filesize mismatch on file \"%s\")", idata->phar->fname, internal_file); + php_stream_close(idata->fp); + efree(idata); + efree(internal_file); + return NULL; + } php_stream_seek(fp, offset + idata->internal_file->compressed_filesize, SEEK_SET); } else { /* from here is for non-compressed */ buffer = &tmpbuf[0]; diff --git a/ext/phar/tests/015.phpt b/ext/phar/tests/015.phpt index 9771bedaff..69c9472e64 100644 --- a/ext/phar/tests/015.phpt +++ b/ext/phar/tests/015.phpt @@ -2,7 +2,7 @@ Phar::mapPhar valid file (gzipped) --SKIPIF-- +if (!Phar::canCompress()) print "skip"; ?> --FILE-- +if (!Phar::canCompress()) print "skip"; ?> --FILE-- "; // file length is too short $files = array(); -$files['a'] = 'a'; +$files['a'] = array('a', chr(75)/*. chr(4) . chr(0): 'a' gzdeflated */, 0x01); +$files['b'] = array('a', chr(75)/*. chr(4) . chr(0): 'a' gzdeflated */, 0x01); +$files['c'] = array('*', '*', 0x00); +$files['d'] = array('a', chr(75)/*. chr(4) . chr(0): 'a' gzdeflated */, 0x01); $manifest = ''; foreach($files as $name => $cont) { - $len = strlen($cont); - $manifest .= pack('V', strlen($name)) . $name . pack('VVVVC', $len, time(), 1, crc32($cont), 0x01); + $ulen = strlen($cont[0]); + $clen = strlen($cont[1]); + $manifest .= pack('V', strlen($name)) . $name + . pack('VVVVC', $ulen, time(), $clen, crc32($cont[0]), $cont[2]); } $alias = 'hio'; $manifest = pack('VnV', count($files), 0x0800, strlen($alias)) . $alias . $manifest; $file .= pack('V', strlen($manifest)) . $manifest; foreach($files as $cont) { - $file .= chr(75) . chr(4) . chr(0); // 'a' gzdeflated + $file .= $cont[1]; } file_put_contents(dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.php', $file); include dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.php'; -echo file_get_contents('phar://hio/a'); +var_dump(file_get_contents('phar://hio/a')); +var_dump(file_get_contents('phar://hio/b')); +var_dump(file_get_contents('phar://hio/c')); +var_dump(file_get_contents('phar://hio/d')); ?> --CLEAN-- --EXPECTF-- -Warning: file_get_contents(phar://hio/a): failed to open stream: phar error: decompression failed in %s on line %d \ No newline at end of file +Warning: file_get_contents(phar://hio/a): failed to open stream: phar error: internal corruption of phar "%s" (actual filesize mismatch on file "a") in %s on line %d +bool(false) + +Warning: file_get_contents(phar://hio/b): failed to open stream: phar error: internal corruption of phar "%s" (actual filesize mismatch on file "b") in %s on line %d +bool(false) +string(1) "*" + +Warning: file_get_contents(phar://hio/d): failed to open stream: phar error: internal corruption of phar "%s" (actual filesize mismatch on file "d") in %s on line %d +bool(false) diff --git a/ext/phar/tests/016b.phpt b/ext/phar/tests/016b.phpt index db9df5853d..00b17a3297 100755 --- a/ext/phar/tests/016b.phpt +++ b/ext/phar/tests/016b.phpt @@ -2,7 +2,7 @@ Phar::mapPhar invalid file (gzipped file length is too short) --SKIPIF-- +if (!Phar::canCompress()) print "skip"; ?> --FILE-- $cont) { $len = strlen($cont); - $manifest .= pack('V', strlen($name)) . $name . pack('VVVVC', $len, time(), 3, crc32($cont), 0x01); + $manifest .= pack('V', strlen($name)) . $name . pack('VVVVC', $len, time(), 1, crc32($cont), 0x01); } $alias = 'hio'; $manifest = pack('VnV', count($files), 0x0800, strlen($alias)) . $alias . $manifest; -- 2.40.0