]> granicus.if.org Git - php/commitdiff
MFB: increase code coverage, fix bzip2-compressed alias in zip
authorGreg Beaver <cellog@php.net>
Sun, 14 Sep 2008 06:32:52 +0000 (06:32 +0000)
committerGreg Beaver <cellog@php.net>
Sun, 14 Sep 2008 06:32:52 +0000 (06:32 +0000)
ext/phar/phar_internal.h
ext/phar/tests/zip/bzip2.phpt
ext/phar/tests/zip/files/bz2_alias.phar.zip [new file with mode: 0644]
ext/phar/zip.c

index fbe2cc5771bdc81f8dec127f225ed215e5f1af80..ed042e97465b7b6fde708bf1dd43b89abbee0e8d 100755 (executable)
@@ -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));
 }
 /* }}} */
 
index f34f1859cd85af6566f11f7b1ad0ceab0d81de2c..208f79a47b610f206b26822333e79279f6ae57ce 100644 (file)
@@ -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
new file mode 100644 (file)
index 0000000..2bab490
Binary files /dev/null and b/ext/phar/tests/zip/files/bz2_alias.phar.zip differ
index 26d873239f92b6ee6cc09f4ea5dca0d93493e14e..a685d995da86b796cfe4623b894b0721116093ea 100644 (file)
@@ -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) {
@@ -497,7 +514,6 @@ foundit:
                                        PHAR_ZIP_FAIL("unable to read in alias, bzip2 filter creation failed");
                                }
 
-                               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) {