]> granicus.if.org Git - php/commitdiff
new test for corrupted zip with mis-matched entry counts, and fix memleaks in this...
authorGreg Beaver <cellog@php.net>
Sat, 19 Apr 2008 05:30:48 +0000 (05:30 +0000)
committerGreg Beaver <cellog@php.net>
Sat, 19 Apr 2008 05:30:48 +0000 (05:30 +0000)
ext/phar/tests/zip/files/corrupt_count1.php.inc [new file with mode: 0644]
ext/phar/tests/zip/files/count1.zip [new file with mode: 0644]
ext/phar/tests/zip/files/count2.zip [new file with mode: 0644]
ext/phar/zip.c

diff --git a/ext/phar/tests/zip/files/corrupt_count1.php.inc b/ext/phar/tests/zip/files/corrupt_count1.php.inc
new file mode 100644 (file)
index 0000000..59017d6
--- /dev/null
@@ -0,0 +1,8 @@
+<?php
+include dirname(__FILE__) . '/corrupt_zipmaker.php.inc';
+$a = new corrupt_zipmaker;
+$a->addFile('hi', null, 'hii');
+$a->addFile('hi2', null, 'hii2');
+$a->writeZip(dirname(__FILE__) . '/count1.zip', 'count1');
+$a->writeZip(dirname(__FILE__) . '/count2.zip', 'count2');
+?>
diff --git a/ext/phar/tests/zip/files/count1.zip b/ext/phar/tests/zip/files/count1.zip
new file mode 100644 (file)
index 0000000..3b95772
Binary files /dev/null and b/ext/phar/tests/zip/files/count1.zip differ
diff --git a/ext/phar/tests/zip/files/count2.zip b/ext/phar/tests/zip/files/count2.zip
new file mode 100644 (file)
index 0000000..8dfd82e
Binary files /dev/null and b/ext/phar/tests/zip/files/count2.zip differ
index 29e4bbbe4a351af0799a5e57899ce9512a6998ba..4581676f9e09c2faad6795c8cadc13f3dd2f2bac 100644 (file)
@@ -158,6 +158,9 @@ int phar_open_zipfile(php_stream *fp, char *fname, int fname_len, char *alias, i
                size = sizeof(locator) + 65536;
                if (FAILURE == php_stream_seek(fp, -size, SEEK_END)) {
                        php_stream_close(fp);
+                       if (error) {
+                               spprintf(error, 4096, "phar error: unable to search for end of central directory in zip-based phar \"%s\"", fname);
+                       }
                        return FAILURE;
                }
        } else {
@@ -165,6 +168,9 @@ int phar_open_zipfile(php_stream *fp, char *fname, int fname_len, char *alias, i
        }
        if (!(read = php_stream_read(fp, buf, size))) {
                php_stream_close(fp);
+               if (error) {
+                       spprintf(error, 4096, "phar error: unable to read in data to search for end of central directory in zip-based phar \"%s\"", fname);
+               }
                return FAILURE;
        }
        while ((p=(char *) memchr(p + 1, 'P', (size_t)(buf - (p+1) + sizeof(locator) + 65536 - 4 + 1))) != NULL) {
@@ -174,11 +180,24 @@ int phar_open_zipfile(php_stream *fp, char *fname, int fname_len, char *alias, i
                }
        }
        php_stream_close(fp);
+       if (error) {
+               spprintf(error, 4096, "phar error: end of central directory not found in zip-based phar \"%s\"", fname);
+       }
        return FAILURE;
 foundit:
        if (locator.centraldisk != 0 || locator.disknumber != 0) {
                /* split archives not handled */
                php_stream_close(fp);
+               if (error) {
+                       spprintf(error, 4096, "phar error: split archives spanning multiple zips cannot be processed in zip-based phar \"%s\"", fname);
+               }
+               return FAILURE;
+       }
+       if (locator.counthere != locator.count) {
+               if (error) {
+                       spprintf(error, 4096, "phar error: corrupt zip archive, conflicting file count in end of central directory record in zip-based phar \"%s\"", fname);
+               }
+               php_stream_close(fp);
                return FAILURE;
        }
        mydata = ecalloc(sizeof(phar_archive_data), 1);