diff options
author | Greg Beaver <cellog@php.net> | 2008-09-14 06:32:52 +0000 |
---|---|---|
committer | Greg Beaver <cellog@php.net> | 2008-09-14 06:32:52 +0000 |
commit | 2f54ca9c7a3ca5b728cff4cc24c4138bf1410108 (patch) | |
tree | feacc0795f4346281a28b3b2ed4083eea3e756c4 /ext/phar | |
parent | a3bec0afb4af2e41e29fc9aa0c652373d58cc8d5 (diff) | |
download | php-git-2f54ca9c7a3ca5b728cff4cc24c4138bf1410108.tar.gz |
MFB: increase code coverage, fix bzip2-compressed alias in zip
Diffstat (limited to 'ext/phar')
-rwxr-xr-x | ext/phar/phar_internal.h | 2 | ||||
-rw-r--r-- | ext/phar/tests/zip/bzip2.phpt | 3 | ||||
-rw-r--r-- | ext/phar/tests/zip/files/bz2_alias.phar.zip | bin | 0 -> 382 bytes | |||
-rw-r--r-- | ext/phar/zip.c | 22 |
4 files changed, 23 insertions, 4 deletions
diff --git a/ext/phar/phar_internal.h b/ext/phar/phar_internal.h index fbe2cc5771..ed042e9746 100755 --- a/ext/phar/phar_internal.h +++ b/ext/phar/phar_internal.h @@ -555,7 +555,7 @@ static inline void phar_unixify_path_separators(char *path, int path_len) static inline int phar_validate_alias(const char *alias, int alias_len) /* {{{ */ { return !(memchr(alias, '/', alias_len) || memchr(alias, '\\', alias_len) || memchr(alias, ':', alias_len) || - memchr(alias, ';', alias_len)); + memchr(alias, ';', alias_len) || memchr(alias, '\n', alias_len) || memchr(alias, '\r', alias_len)); } /* }}} */ diff --git a/ext/phar/tests/zip/bzip2.phpt b/ext/phar/tests/zip/bzip2.phpt index f34f1859cd..208f79a47b 100644 --- a/ext/phar/tests/zip/bzip2.phpt +++ b/ext/phar/tests/zip/bzip2.phpt @@ -11,6 +11,8 @@ try { foreach ($a as $entry => $file) { echo $file->getContent(); } + $a = new Phar(dirname(__FILE__) . '/files/bz2_alias.phar.zip'); + var_dump($a->getAlias()); } catch (Exception $e) { echo $e->getMessage() . "\n"; } @@ -77,4 +79,5 @@ $a = new corrupt_zipmaker; $a->addFile('hi', null, 'hii', null, null, 'compress', 'compress', 11); $a->writeZip(dirname(__FILE__) . '/compress_unsupunknown.zip'); ?> +string(7) "hithere" ===DONE=== diff --git a/ext/phar/tests/zip/files/bz2_alias.phar.zip b/ext/phar/tests/zip/files/bz2_alias.phar.zip Binary files differnew file mode 100644 index 0000000000..2bab490a88 --- /dev/null +++ b/ext/phar/tests/zip/files/bz2_alias.phar.zip diff --git a/ext/phar/zip.c b/ext/phar/zip.c index 26d873239f..a685d995da 100644 --- a/ext/phar/zip.c +++ b/ext/phar/zip.c @@ -465,10 +465,27 @@ foundit: if (!actual_alias && entry.filename_len == sizeof(".phar/alias.txt")-1 && !strncmp(entry.filename, ".phar/alias.txt", sizeof(".phar/alias.txt")-1)) { php_stream_filter *filter; off_t saveloc; + /* verify local file header */ + phar_zip_file_header local; - /* archive alias found, seek to file contents, do not validate local header. Potentially risky, but not very. */ + /* archive alias found */ saveloc = php_stream_tell(fp); - php_stream_seek(fp, PHAR_GET_32(zipentry.offset) + sizeof(phar_zip_file_header) + entry.filename_len + PHAR_GET_16(zipentry.extra_len), SEEK_SET); + php_stream_seek(fp, PHAR_GET_32(zipentry.offset), SEEK_SET); + + if (sizeof(local) != php_stream_read(fp, (char *) &local, sizeof(local))) { + PHAR_ZIP_FAIL("phar error: internal corruption of zip-based phar (cannot read local file header for alias)"); + } + + /* verify local header */ + if (entry.filename_len != PHAR_GET_16(local.filename_len) || entry.crc32 != PHAR_GET_32(local.crc32) || entry.uncompressed_filesize != PHAR_GET_32(local.uncompsize) || entry.compressed_filesize != PHAR_GET_32(local.compsize)) { + PHAR_ZIP_FAIL("phar error: internal corruption of zip-based phar (local head of alias does not match central directory)"); + } + + /* construct actual offset to file start - local extra_len can be different from central extra_len */ + entry.offset = entry.offset_abs = + sizeof(local) + entry.header_offset + PHAR_GET_16(local.filename_len) + PHAR_GET_16(local.extra_len); + php_stream_seek(fp, entry.offset, SEEK_SET); + mydata->alias_len = entry.uncompressed_filesize; if (entry.flags & PHAR_ENT_COMPRESSED_GZ) { @@ -498,7 +515,6 @@ foundit: } php_stream_filter_append(&fp->readfilters, filter); - php_stream_filter_append(&fp->readfilters, filter); if (!(entry.uncompressed_filesize = php_stream_copy_to_mem(fp, &actual_alias, entry.uncompressed_filesize, 0)) || !actual_alias) { pefree(entry.filename, entry.is_persistent); |