]> granicus.if.org Git - php/commitdiff
fix PHP Bug #49910: no support for ././@LongLink for long filenames in phar tar support
authorGreg Beaver <cellog@php.net>
Wed, 11 Nov 2009 21:02:59 +0000 (21:02 +0000)
committerGreg Beaver <cellog@php.net>
Wed, 11 Nov 2009 21:02:59 +0000 (21:02 +0000)
ext/phar/php_phar.h
ext/phar/tar.c
ext/phar/tests/tar/bug49910.phpt [new file with mode: 0644]
ext/phar/tests/tar/files/Structures_Graph-1.0.3.tgz [new file with mode: 0644]

index c8535fb7f476464256e23063c32abf33f2c14962..e765ad4c5c9a895910c807bf8aaa6d6a1db4ad67 100644 (file)
@@ -22,7 +22,7 @@
 #ifndef PHP_PHAR_H
 #define PHP_PHAR_H
 
-#define PHP_PHAR_VERSION "2.0.0"
+#define PHP_PHAR_VERSION "2.0.1"
 
 #include "ext/standard/basic_functions.h"
 extern zend_module_entry phar_module_entry;
index 383356fb93b8b2f11244487a1f670265b3cbaedb..53255b1d2d9e05a3aa16a9fc3a1f9eaa4c20691e 100644 (file)
@@ -200,6 +200,7 @@ int phar_parse_tarfile(php_stream* fp, char *fname, int fname_len, char *alias,
        tar_header *hdr;
        php_uint32 sum1, sum2, size, old;
        phar_archive_data *myphar, **actual;
+       int last_was_longlink = 0;
 
        if (error) {
                *error = NULL;
@@ -332,7 +333,52 @@ bail:
                        goto bail;
                }
 
-               if (!old && hdr->prefix[0] != 0) {
+               if (!last_was_longlink && hdr->typeflag == 'L') {
+                       last_was_longlink = 1;
+                       /* support the ././@LongLink system for storing long filenames */
+                       entry.filename_len = entry.uncompressed_filesize;
+                       entry.filename = pemalloc(entry.filename_len+1, myphar->is_persistent);
+
+                       read = php_stream_read(fp, entry.filename, entry.filename_len);
+                       if (read != entry.filename_len) {
+                               efree(entry.filename);
+                               if (error) {
+                                       spprintf(error, 4096, "phar error: \"%s\" is a corrupted tar file (truncated)", fname);
+                               }
+                               php_stream_close(fp);
+                               phar_destroy_phar_data(myphar TSRMLS_CC);
+                               return FAILURE;
+                       }
+                       entry.filename[entry.filename_len] = '\0';
+
+                       /* skip blank stuff */
+                       size = ((size+511)&~511) - size;
+
+                       /* this is not good enough - seek succeeds even on truncated tars */
+                       php_stream_seek(fp, size, SEEK_CUR);
+                       if ((uint)php_stream_tell(fp) > totalsize) {
+                               efree(entry.filename);
+                               if (error) {
+                                       spprintf(error, 4096, "phar error: \"%s\" is a corrupted tar file (truncated)", fname);
+                               }
+                               php_stream_close(fp);
+                               phar_destroy_phar_data(myphar TSRMLS_CC);
+                               return FAILURE;
+                       }
+
+                       read = php_stream_read(fp, buf, sizeof(buf));
+       
+                       if (read != sizeof(buf)) {
+                               efree(entry.filename);
+                               if (error) {
+                                       spprintf(error, 4096, "phar error: \"%s\" is a corrupted tar file (truncated)", fname);
+                               }
+                               php_stream_close(fp);
+                               phar_destroy_phar_data(myphar TSRMLS_CC);
+                               return FAILURE;
+                       }
+                       continue;
+               } else if (!last_was_longlink && !old && hdr->prefix[0] != 0) {
                        char name[256];
                        int i, j;
 
@@ -357,7 +403,7 @@ bail:
                                entry.filename_len--;
                        }
                        entry.filename = pestrndup(name, entry.filename_len, myphar->is_persistent);
-               } else {
+               } else if (!last_was_longlink) {
                        int i;
 
                        /* calculate strlen, which can be no longer than 100 */
@@ -375,6 +421,7 @@ bail:
                                entry.filename_len--;
                        }
                }
+               last_was_longlink = 0;
 
                phar_add_virtual_dirs(myphar, entry.filename, entry.filename_len TSRMLS_CC);
 
diff --git a/ext/phar/tests/tar/bug49910.phpt b/ext/phar/tests/tar/bug49910.phpt
new file mode 100644 (file)
index 0000000..c799d52
--- /dev/null
@@ -0,0 +1,49 @@
+--TEST--
+Bug #49910: no support for ././@LongLink for long filenames in phar tar support
+--SKIPIF--
+<?php if (!extension_loaded("phar")) die("skip"); ?>
+--FILE--
+<?php
+$fname = str_replace('\\', '/', dirname(__FILE__) . '/files/Structures_Graph-1.0.3.tgz');
+$tar = new PharData($fname);
+$files = array();
+foreach (new RecursiveIteratorIterator($tar) as $file) {
+       $files[] = str_replace($fname, '*', $file->getPathName());
+}
+print_r($files);
+?>
+===DONE===
+--EXPECT--
+Array
+(
+    [0] => phar://*/Structures_Graph-1.0.3/LICENSE
+    [1] => phar://*/Structures_Graph-1.0.3/Structures/Graph/Manipulator/AcyclicTest.php
+    [2] => phar://*/Structures_Graph-1.0.3/Structures/Graph/Manipulator/TopologicalSorter.php
+    [3] => phar://*/Structures_Graph-1.0.3/Structures/Graph/Node.php
+    [4] => phar://*/Structures_Graph-1.0.3/Structures/Graph.php
+    [5] => phar://*/Structures_Graph-1.0.3/docs/generate.sh
+    [6] => phar://*/Structures_Graph-1.0.3/docs/html/Structures_Graph/Structures_Graph.html
+    [7] => phar://*/Structures_Graph-1.0.3/docs/html/Structures_Graph/Structures_Graph_Manipulator_AcyclicTest.html
+    [8] => phar://*/Structures_Graph-1.0.3/docs/html/Structures_Graph/Structures_Graph_Manipulator_TopologicalSorter.html
+    [9] => phar://*/Structures_Graph-1.0.3/docs/html/Structures_Graph/Structures_Graph_Node.html
+    [10] => phar://*/Structures_Graph-1.0.3/docs/html/Structures_Graph/_Structures_Graph_Manipulator_AcyclicTest_php.html
+    [11] => phar://*/Structures_Graph-1.0.3/docs/html/Structures_Graph/_Structures_Graph_Manipulator_TopologicalSorter_php.html
+    [12] => phar://*/Structures_Graph-1.0.3/docs/html/Structures_Graph/_Structures_Graph_Node_php.html
+    [13] => phar://*/Structures_Graph-1.0.3/docs/html/Structures_Graph/_Structures_Graph_php.html
+    [14] => phar://*/Structures_Graph-1.0.3/docs/html/Structures_Graph/tutorial_Structures_Graph.pkg.html
+    [15] => phar://*/Structures_Graph-1.0.3/docs/html/classtrees_Structures_Graph.html
+    [16] => phar://*/Structures_Graph-1.0.3/docs/html/elementindex.html
+    [17] => phar://*/Structures_Graph-1.0.3/docs/html/elementindex_Structures_Graph.html
+    [18] => phar://*/Structures_Graph-1.0.3/docs/html/errors.html
+    [19] => phar://*/Structures_Graph-1.0.3/docs/html/index.html
+    [20] => phar://*/Structures_Graph-1.0.3/docs/html/li_Structures_Graph.html
+    [21] => phar://*/Structures_Graph-1.0.3/docs/html/media/banner.css
+    [22] => phar://*/Structures_Graph-1.0.3/docs/html/media/stylesheet.css
+    [23] => phar://*/Structures_Graph-1.0.3/docs/html/packages.html
+    [24] => phar://*/Structures_Graph-1.0.3/docs/html/todolist.html
+    [25] => phar://*/Structures_Graph-1.0.3/docs/tutorials/Structures_Graph/Structures_Graph.pkg
+    [26] => phar://*/Structures_Graph-1.0.3/tests/AllTests.php
+    [27] => phar://*/Structures_Graph-1.0.3/tests/testCase/BasicGraph.php
+    [28] => phar://*/package.xml
+)
+===DONE===
\ No newline at end of file
diff --git a/ext/phar/tests/tar/files/Structures_Graph-1.0.3.tgz b/ext/phar/tests/tar/files/Structures_Graph-1.0.3.tgz
new file mode 100644 (file)
index 0000000..fa14f0c
Binary files /dev/null and b/ext/phar/tests/tar/files/Structures_Graph-1.0.3.tgz differ