]> granicus.if.org Git - php/commitdiff
add screening of alias to reading of zip archives, and test for bad aliases
authorGreg Beaver <cellog@php.net>
Sat, 26 Apr 2008 22:04:04 +0000 (22:04 +0000)
committerGreg Beaver <cellog@php.net>
Sat, 26 Apr 2008 22:04:04 +0000 (22:04 +0000)
ext/phar/tests/zip/badalias.phpt [new file with mode: 0644]
ext/phar/tests/zip/files/badalias1.phar.zip [new file with mode: 0644]
ext/phar/tests/zip/files/badalias2.phar.zip [new file with mode: 0644]
ext/phar/tests/zip/files/badalias3.phar.zip [new file with mode: 0644]
ext/phar/tests/zip/files/badalias4.phar.zip [new file with mode: 0644]
ext/phar/tests/zip/files/badalias5.phar.zip [new file with mode: 0644]
ext/phar/zip.c

diff --git a/ext/phar/tests/zip/badalias.phpt b/ext/phar/tests/zip/badalias.phpt
new file mode 100644 (file)
index 0000000..4e08cef
--- /dev/null
@@ -0,0 +1,25 @@
+--TEST--
+Phar: invalid aliases
+--SKIPIF--
+<?php if (!extension_loaded("phar")) die("skip"); ?>
+<?php if (!extension_loaded("zlib")) die("skip no zlib"); ?>
+<?php if (!extension_loaded("bz2")) die("skip no bz2"); ?>
+--FILE--
+<?php
+$e = dirname(__FILE__) . '/files/';
+for ($i = 1; $i <= 5; $i++) {
+try {
+new Phar($e . "badalias$i.phar.zip");
+} catch (Exception $ee) {
+echo $ee->getMessage(), "\n";
+}
+}
+?>
+===DONE===
+--EXPECTF--
+phar error: invalid alias in zip-based phar "%sbadalias1.phar.zip"
+phar error: invalid alias in zip-based phar "%sbadalias2.phar.zip"
+phar error: invalid alias in zip-based phar "%sbadalias3.phar.zip"
+phar error: invalid alias in zip-based phar "%sbadalias4.phar.zip"
+phar error: invalid alias in zip-based phar "%sbadalias5.phar.zip"
+===DONE===
diff --git a/ext/phar/tests/zip/files/badalias1.phar.zip b/ext/phar/tests/zip/files/badalias1.phar.zip
new file mode 100644 (file)
index 0000000..0e3adfc
Binary files /dev/null and b/ext/phar/tests/zip/files/badalias1.phar.zip differ
diff --git a/ext/phar/tests/zip/files/badalias2.phar.zip b/ext/phar/tests/zip/files/badalias2.phar.zip
new file mode 100644 (file)
index 0000000..7b5baaa
Binary files /dev/null and b/ext/phar/tests/zip/files/badalias2.phar.zip differ
diff --git a/ext/phar/tests/zip/files/badalias3.phar.zip b/ext/phar/tests/zip/files/badalias3.phar.zip
new file mode 100644 (file)
index 0000000..7b5baaa
Binary files /dev/null and b/ext/phar/tests/zip/files/badalias3.phar.zip differ
diff --git a/ext/phar/tests/zip/files/badalias4.phar.zip b/ext/phar/tests/zip/files/badalias4.phar.zip
new file mode 100644 (file)
index 0000000..49b7be0
Binary files /dev/null and b/ext/phar/tests/zip/files/badalias4.phar.zip differ
diff --git a/ext/phar/tests/zip/files/badalias5.phar.zip b/ext/phar/tests/zip/files/badalias5.phar.zip
new file mode 100644 (file)
index 0000000..9f2b0e8
Binary files /dev/null and b/ext/phar/tests/zip/files/badalias5.phar.zip differ
index 886cb20c5da2d71b3c0fc6ac528cf4535b17f28d..bf613a31f587be315322aa60c5761ef0ab426ca0 100644 (file)
@@ -317,12 +317,14 @@ foundit:
                        case PHAR_ZIP_COMP_DEFLATE :
                                entry.flags |= PHAR_ENT_COMPRESSED_GZ;
                                if (!phar_has_zlib) {
+                                       efree(entry.filename);
                                        PHAR_ZIP_FAIL("zlib extension is required");
                                }
                                break;
                        case PHAR_ZIP_COMP_BZIP2 :
                                entry.flags |= PHAR_ENT_COMPRESSED_BZ2;
                                if (!phar_has_bz2) {
+                                       efree(entry.filename);
                                        PHAR_ZIP_FAIL("bzip2 extension is required");
                                }
                                break;
@@ -369,6 +371,7 @@ foundit:
                /* get file metadata */
                if (zipentry.comment_len) {
                        if (PHAR_GET_16(zipentry.comment_len) != php_stream_read(fp, buf, PHAR_GET_16(zipentry.comment_len))) {
+                               efree(entry.filename);
                                PHAR_ZIP_FAIL("unable to read in file comment, truncated");
                        }
                        p = buf;
@@ -391,10 +394,12 @@ foundit:
                        if (entry.flags & PHAR_ENT_COMPRESSED_GZ) {
                                filter = php_stream_filter_create("zlib.inflate", NULL, php_stream_is_persistent(fp) TSRMLS_CC);
                                if (!filter) {
+                                       efree(entry.filename);
                                        PHAR_ZIP_FAIL("unable to decompress alias, zlib filter creation failed");
                                }
                                php_stream_filter_append(&fp->readfilters, filter);
                                if (!(entry.uncompressed_filesize = php_stream_copy_to_mem(fp, &(mydata->alias), entry.uncompressed_filesize, 0)) || !mydata->alias) {
+                                       efree(entry.filename);
                                        PHAR_ZIP_FAIL("unable to read in alias, truncated");
                                }
                                php_stream_filter_flush(filter, 1);
@@ -403,23 +408,30 @@ foundit:
                                php_stream_filter *filter;
                                filter = php_stream_filter_create("bzip2.decompress", NULL, php_stream_is_persistent(fp) TSRMLS_CC);
                                if (!filter) {
+                                       efree(entry.filename);
                                        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, &(mydata->alias), entry.uncompressed_filesize, 0)) || !mydata->alias) {
+                                       efree(entry.filename);
                                        PHAR_ZIP_FAIL("unable to read in alias, truncated");
                                }
                                php_stream_filter_flush(filter, 1);
                                php_stream_filter_remove(filter, 1 TSRMLS_CC);
                        } else {
                                if (!(entry.uncompressed_filesize = php_stream_copy_to_mem(fp, &(mydata->alias), entry.uncompressed_filesize, 0)) || !mydata->alias) {
+                                       efree(entry.filename);
                                        PHAR_ZIP_FAIL("unable to read in alias, truncated");
                                }
                        }
 
                        mydata->is_temporary_alias = 0;
                        mydata->alias_len = PHAR_GET_32(zipentry.uncompsize);
+                       if (!phar_validate_alias(mydata->alias, mydata->alias_len)) {
+                               efree(entry.filename);
+                               PHAR_ZIP_FAIL("invalid alias");
+                       }
                        zend_hash_add(&(PHAR_GLOBALS->phar_alias_map), mydata->alias, mydata->alias_len, (void*)&mydata, sizeof(phar_archive_data*), NULL);
                        /* return to central directory parsing */
                        php_stream_seek(fp, saveloc, SEEK_SET);