]> granicus.if.org Git - php/commitdiff
implement cleaning of crap paths - major functionality boost
authorGreg Beaver <cellog@php.net>
Thu, 20 Dec 2007 23:12:40 +0000 (23:12 +0000)
committerGreg Beaver <cellog@php.net>
Thu, 20 Dec 2007 23:12:40 +0000 (23:12 +0000)
ext/phar/TODO
ext/phar/package.php
ext/phar/package.xml
ext/phar/phar.c
ext/phar/phar_internal.h
ext/phar/tests/phar_magic.phpt

index 88f0f7ca425858b81d07e70e1c1814832c969d73..e7669b614bddd3d72ba0dd0afa60f3ef00bb3195 100644 (file)
@@ -64,7 +64,6 @@ Version 1.3.0
    __HALT_COMPILER();function __HALT_COMPILER(){}$a=<<<PHARDATABEGIN\n
  * ability to have Phar object return file class as offsetGet() result
  * ability to store empty directories
- * [optional] Phar->rollback() to abort a write transaction
  * implement PPG signing
  * ability to match files containing a metadata key opendir('phar://a.phar/?mime-type=image/jpeg')
    or foreach ($p->match('mime-type', 'image/jpeg') as $file)
@@ -73,4 +72,4 @@ Version 1.3.0
  X Phar::buildFromIterator(Iterator $it[, string $base_directory]) [Greg]
  * Layout: Option to compress all content rather than single files.
    That excludes stub and manifest haeder.
- * stream context option for cleaning crap paths like phar://blah.phar/file//to\\here.php
+ X clean crap paths like phar://blah.phar/file//../to\\here.php [Greg]
index 078e1811fb8ab445feae6a1d5a86e3374cc84047..c5a8f49cbc8d5926d6952a2a7f2dcfed4973949d 100644 (file)
@@ -1,6 +1,9 @@
 <?php
 
 $notes = '
+Major feature functionality release
+ * include/getcwd/fopen with include_path all work unmodified within a phar
+ * paths with . and .. work (phar://blah.phar/a/../b.php => phar://blah.phar/b.php)
  * implement Phar::copy(string $from, string $to) [Greg]
  * implement Phar::buildFromIterator(Iterator $it[, string $base_directory]) [Greg]
  * add mapping of include/require from within a phar to location within phar [Greg]
index b2f8aa869e466aa97e0153de53e827a83799649d..abeb2296d20d5a1d2d2cfdeb8e469e602e629158 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<package packagerversion="1.7.0RC1" version="2.0" xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0 http://pear.php.net/dtd/tasks-1.0.xsd http://pear.php.net/dtd/package-2.0 http://pear.php.net/dtd/package-2.0.xsd">
+<package packagerversion="1.6.1" version="2.0" xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0 http://pear.php.net/dtd/tasks-1.0.xsd http://pear.php.net/dtd/package-2.0 http://pear.php.net/dtd/package-2.0.xsd">
  <name>phar</name>
  <channel>pecl.php.net</channel>
  <summary>allows running of complete applications out of .phar files (like Java .jar files)</summary>
@@ -29,8 +29,8 @@ avaiable then SHA-256 and SHA-512 signatures are supported as well.</description
   <email>helly@php.net</email>
   <active>yes</active>
  </lead>
- <date>2007-12-12</date>
- <time>11:56:58</time>
+ <date>2007-12-20</date>
+ <time>17:12:06</time>
  <version>
   <release>1.3.0</release>
   <api>1.1.0</api>
@@ -42,6 +42,10 @@ avaiable then SHA-256 and SHA-512 signatures are supported as well.</description
  <license uri="http://www.php.net/license">PHP License</license>
  <notes>
 
+Major feature functionality release
+ * include/getcwd/fopen with include_path all work unmodified within a phar
+ * paths with . and .. work (phar://blah.phar/a/../b.php =&gt; phar://blah.phar/b.php)
+ * implement Phar::copy(string $from, string $to) [Greg]
  * implement Phar::buildFromIterator(Iterator $it[, string $base_directory]) [Greg]
  * add mapping of include/require from within a phar to location within phar [Greg]
    solves the include_path issue without code munging
@@ -123,7 +127,17 @@ avaiable then SHA-256 and SHA-512 signatures are supported as well.</description
     <file name="open_for_write_newfile_b.phpt" role="test" />
     <file name="open_for_write_newfile_c.phpt" role="test" />
     <file name="phar_begin_setstub_commit.phpt" role="test" />
+    <file name="phar_buildfromiterator1.phpt" role="test" />
+    <file name="phar_buildfromiterator2.phpt" role="test" />
+    <file name="phar_buildfromiterator3.phpt" role="test" />
+    <file name="phar_buildfromiterator4.phpt" role="test" />
+    <file name="phar_buildfromiterator5.phpt" role="test" />
+    <file name="phar_buildfromiterator6.phpt" role="test" />
+    <file name="phar_buildfromiterator7.phpt" role="test" />
+    <file name="phar_buildfromiterator8.phpt" role="test" />
+    <file name="phar_buildfromiterator9.phpt" role="test" />
     <file name="phar_commitwrite.phpt" role="test" />
+    <file name="phar_copy.phpt" role="test" />
     <file name="phar_create_in_cwd.phpt" role="test" />
     <file name="phar_ctx_001.phpt" role="test" />
     <file name="phar_dir_iterate.phpt" role="test" />
@@ -133,6 +147,7 @@ avaiable then SHA-256 and SHA-512 signatures are supported as well.</description
     <file name="phar_get_supportedcomp4.phpt" role="test" />
     <file name="phar_get_suppoted_signatures_001.phpt" role="test" />
     <file name="phar_get_suppoted_signatures_002.phpt" role="test" />
+    <file name="phar_magic.phpt" role="test" />
     <file name="phar_metadata_read.phpt" role="test" />
     <file name="phar_metadata_write.phpt" role="test" />
     <file name="phar_offset_get_error.phpt" role="test" />
@@ -235,10 +250,14 @@ avaiable then SHA-256 and SHA-512 signatures are supported as well.</description
     <release>stable</release>
     <api>stable</api>
    </stability>
-   <date>2007-12-12</date>
+   <date>2007-12-20</date>
    <license uri="http://www.php.net/license">PHP License</license>
    <notes>
 
+Major feature functionality release
+ * include/getcwd/fopen with include_path all work unmodified within a phar
+ * paths with . and .. work (phar://blah.phar/a/../b.php =&gt; phar://blah.phar/b.php)
+ * implement Phar::copy(string $from, string $to) [Greg]
  * implement Phar::buildFromIterator(Iterator $it[, string $base_directory]) [Greg]
  * add mapping of include/require from within a phar to location within phar [Greg]
    solves the include_path issue without code munging
index 13204fd35d1d850928940f130cc212a890c813d0..67b16b1422e6ef04c831cf058aed9aca3da589df 100644 (file)
@@ -1562,6 +1562,92 @@ int phar_detect_phar_fname_ext(const char *filename, int check_length, char **ex
 }
 /* }}} */
 
+static int php_check_dots(const char *element, int n) 
+{
+       while (n-- > 0) if (element[n] != '.') break;
+
+       return (n != -1);
+}
+
+#define IS_DIRECTORY_UP(element, len) \
+       (len >= 2 && !php_check_dots(element, len))
+
+#define IS_DIRECTORY_CURRENT(element, len) \
+       (len == 1 && element[0] == '.')
+
+#define IS_BACKSLASH(c)     ((c) == '/')
+
+/**
+ * Remove .. and . references within a phar filename
+ */
+static char *phar_fix_filepath(char *path, int *new_len) /* {{{ */
+{
+       char *ptr, *free_path, *new_phar;
+       char *tok;
+       int ptr_length, new_phar_len = 1, path_length = *new_len;
+
+       free_path = path;
+       new_phar = estrndup("/\0", 2);
+       tok = NULL;
+       ptr = tsrm_strtok_r(path, "/", &tok);
+       while (ptr) {
+               ptr_length = strlen(ptr);
+
+               if (IS_DIRECTORY_UP(ptr, ptr_length)) {
+                       char save;
+
+                       save = '/';
+
+#define PREVIOUS new_phar[new_phar_len - 1]
+
+                       while (new_phar_len > 1 &&
+                                       !IS_BACKSLASH(PREVIOUS)) {
+                               save = PREVIOUS;
+                               PREVIOUS = '\0';
+                               new_phar_len--;
+                       }
+
+                       if (new_phar[0] != '/') {
+                               new_phar[new_phar_len++] = save;
+                               new_phar[new_phar_len] = '\0';
+                       } else if (new_phar_len > 1) {
+                               PREVIOUS = '\0';
+                               new_phar_len--;
+                       }
+               } else if (!IS_DIRECTORY_CURRENT(ptr, ptr_length)) {
+                       if (new_phar_len > 1) {
+                               new_phar = (char *) erealloc(new_phar, new_phar_len+ptr_length+1+1);
+                               new_phar[new_phar_len++] = '/';
+                               memcpy(&new_phar[new_phar_len], ptr, ptr_length+1);
+                       } else {
+                               new_phar = (char *) erealloc(new_phar, new_phar_len+ptr_length+1);
+                               memcpy(&new_phar[new_phar_len], ptr, ptr_length+1);
+                       }
+
+                       new_phar_len += ptr_length;
+               }
+               ptr = tsrm_strtok_r(NULL, "/", &tok);
+       }
+
+       efree(free_path);
+
+       if (path[path_length-1] == '/') {
+               new_phar = (char*)erealloc(new_phar, new_phar_len + 2);
+               new_phar[new_phar_len++] = '/';
+               new_phar[new_phar_len] = 0;
+       }
+
+       if (new_phar_len == 0) {
+               new_phar = (char *) erealloc(new_phar, new_phar_len+1+1);
+               new_phar[new_phar_len] = '/';
+               new_phar[new_phar_len+1] = '\0';
+               new_phar_len++;
+       }
+       *new_len = new_phar_len;
+       return new_phar;
+}
+/* }}} */
+
 /**
  * Process a phar stream name, ensuring we can handle any of:
  * 
@@ -1608,6 +1694,7 @@ int phar_split_fname(char *filename, int filename_len, char **arch, int *arch_le
 #ifdef PHP_WIN32
                phar_unixify_path_separators(*entry, *entry_len);
 #endif
+       *entry = phar_fix_filepath(*entry, entry_len);
        } else {
                *entry_len = 1;
                *entry = estrndup("/", 1);
@@ -3744,7 +3831,6 @@ static void php_phar_init_globals_module(zend_phar_globals *phar_globals)
        phar_globals->readonly = 1;
 }
 /* }}} */
-
 static zend_op_array *phar_compile_file(zend_file_handle *file_handle, int type TSRMLS_DC) /* {{{ */
 {
        zend_op_array *res;
index f20cc3815322c4518644e4ebe07779581a372701..af2b30291f857802f25cc1ea04a610493df192fb 100755 (executable)
@@ -44,6 +44,7 @@
 #include "ext/standard/sha1.h"
 #include "ext/standard/php_var.h"
 #include "ext/standard/php_smart_str.h"
+#include "TSRM/tsrm_strtok_r.h"
 #if HAVE_SPL
 #include "ext/spl/spl_array.h"
 #include "ext/spl/spl_directory.h"
@@ -252,7 +253,7 @@ int phar_open_or_create_filename(char *fname, int fname_len, char *alias, int al
 int phar_open_compiled_file(char *alias, int alias_len, char **error TSRMLS_DC);
 
 static void phar_fopen(INTERNAL_FUNCTION_PARAMETERS);
-static void phar_cwd(INTERNAL_FUNCTION_PARAMETERS);
+static void phar_getcwd(INTERNAL_FUNCTION_PARAMETERS);
 
 #ifdef PHAR_MAIN
 static void phar_fopen(INTERNAL_FUNCTION_PARAMETERS);
index a813560a9d299da5309c1c42d05a03f4b103fd93..75542b6a5809914209e1e87ed75831b7b8f0cfc7 100644 (file)
@@ -10,7 +10,8 @@ phar.readonly=0
 $fname = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.php';
 $p = new Phar($fname);
 $p['a'] = '<?php include "b/c.php";' . "\n";
-$p['b/c.php'] = '<?php echo "in b\n";$a = fopen("a", "r", true);echo stream_get_contents($a);fclose($a);echo getcwd() . "\n";';
+$p['b/c.php'] = '<?php echo "in b\n";$a = fopen("a", "r", true);echo stream_get_contents($a);fclose($a);echo getcwd() . "\n";include dirname(__FILE__) . "/../d";';
+$p['d'] = "in d\n";
 $p->setStub('<?php
 include "phar://" . __FILE__ . "/a";
 __HALT_COMPILER();');
@@ -26,4 +27,5 @@ __HALT_COMPILER();
 in b
 <?php include "b/c.php";
 phar://%s/b
+in d
 ===DONE===