From: Greg Beaver Date: Thu, 20 Dec 2007 23:12:40 +0000 (+0000) Subject: implement cleaning of crap paths - major functionality boost X-Git-Tag: RELEASE_2_0_0a1~1126 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=0d830a27ea042b1bd9b32a050e6812002b79f487;p=php implement cleaning of crap paths - major functionality boost --- diff --git a/ext/phar/TODO b/ext/phar/TODO index 88f0f7ca42..e7669b614b 100644 --- a/ext/phar/TODO +++ b/ext/phar/TODO @@ -64,7 +64,6 @@ Version 1.3.0 __HALT_COMPILER();function __HALT_COMPILER(){}$a=<<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] diff --git a/ext/phar/package.php b/ext/phar/package.php index 078e1811fb..c5a8f49cbc 100644 --- a/ext/phar/package.php +++ b/ext/phar/package.php @@ -1,6 +1,9 @@ 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] diff --git a/ext/phar/package.xml b/ext/phar/package.xml index b2f8aa869e..abeb2296d2 100644 --- a/ext/phar/package.xml +++ b/ext/phar/package.xml @@ -1,5 +1,5 @@ - + phar pecl.php.net allows running of complete applications out of .phar files (like Java .jar files) @@ -29,8 +29,8 @@ avaiable then SHA-256 and SHA-512 signatures are supported as well.helly@php.net yes - 2007-12-12 - + 2007-12-20 + 1.3.0 1.1.0 @@ -42,6 +42,10 @@ avaiable then SHA-256 and SHA-512 signatures are supported as well.PHP License +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] solves the include_path issue without code munging @@ -123,7 +127,17 @@ avaiable then SHA-256 and SHA-512 signatures are supported as well. + + + + + + + + + + @@ -133,6 +147,7 @@ avaiable then SHA-256 and SHA-512 signatures are supported as well. + @@ -235,10 +250,14 @@ avaiable then SHA-256 and SHA-512 signatures are supported as well.stable stable - 2007-12-12 + 2007-12-20 PHP License +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] solves the include_path issue without code munging diff --git a/ext/phar/phar.c b/ext/phar/phar.c index 13204fd35d..67b16b1422 100644 --- a/ext/phar/phar.c +++ b/ext/phar/phar.c @@ -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; diff --git a/ext/phar/phar_internal.h b/ext/phar/phar_internal.h index f20cc38153..af2b30291f 100755 --- a/ext/phar/phar_internal.h +++ b/ext/phar/phar_internal.h @@ -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); diff --git a/ext/phar/tests/phar_magic.phpt b/ext/phar/tests/phar_magic.phpt index a813560a9d..75542b6a58 100644 --- a/ext/phar/tests/phar_magic.phpt +++ b/ext/phar/tests/phar_magic.phpt @@ -10,7 +10,8 @@ phar.readonly=0 $fname = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.php'; $p = new Phar($fname); $p['a'] = 'setStub('