diff options
| -rw-r--r-- | ext/phar/makestub.php | 51 | ||||
| -rw-r--r-- | ext/phar/phar.c | 7 | ||||
| -rwxr-xr-x | ext/phar/phar_internal.h | 1 | ||||
| -rw-r--r-- | ext/phar/shortarc.php | 176 | ||||
| -rw-r--r-- | ext/phar/stream.c | 16 | ||||
| -rw-r--r-- | ext/phar/stub.h | 21 | ||||
| -rw-r--r-- | ext/phar/tests/nophar.phar | bin | 0 -> 4773 bytes | |||
| -rw-r--r-- | ext/phar/tests/nophar.phar.inc | 8 | ||||
| -rw-r--r-- | ext/phar/tests/nophar.phpt | 14 | ||||
| -rw-r--r-- | ext/phar/tests/phar_commitwrite.phpt | 181 | ||||
| -rw-r--r-- | ext/phar/tests/phar_create_in_cwd.phpt | 5 | ||||
| -rw-r--r-- | ext/phar/tests/withphar.phpt | 14 |
12 files changed, 482 insertions, 12 deletions
diff --git a/ext/phar/makestub.php b/ext/phar/makestub.php new file mode 100644 index 0000000000..4296cab2d5 --- /dev/null +++ b/ext/phar/makestub.php @@ -0,0 +1,51 @@ +<?php +$s = str_replace("\r", '', file_get_contents(dirname(__FILE__) . '/shortarc.php')); +$s .= "\nExtract_Phar::go(XXXX);\n__HALT_COMPILER();"; +$news = ''; +$last = -1; +foreach (token_get_all($s) as $token) { + if (is_array($token)) { + if ($token[0] == T_WHITESPACE) { + if ($last == T_COMMENT) { + $token[1] = ''; + } else { + $n = str_repeat("\n", substr_count($token[1], "\n")); + $token[1] = strlen($n) ? $n : ' '; + } + } + $last = $token[0]; + $news .= $token[1]; + } else { + $news .= $token; + } +} +$s = $news . ' ?>'; +$s = str_replace('XXXX', strlen($s)-1, $s); +$s = str_replace('"', '\\"', $s); +$s = str_replace("\n", '\n', $s); + +$stub = '/* + +----------------------------------------------------------------------+ + | phar php single-file executable PHP extension generated stub | + +----------------------------------------------------------------------+ + | Copyright (c) 2005-' . date('Y') . ' The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt. | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Gregory Beaver <cellog@php.net> | + +----------------------------------------------------------------------+ +*/ + +/* $Id$ */ + +static const char newstub[] = "' . $s . '"; +'; + +file_put_contents(dirname(__FILE__) . '/stub.h', $stub); +?>
\ No newline at end of file diff --git a/ext/phar/phar.c b/ext/phar/phar.c index 92c63dd5d6..38f3f75bc1 100644 --- a/ext/phar/phar.c +++ b/ext/phar/phar.c @@ -2343,7 +2343,8 @@ static int phar_flush_clean_deleted_apply(void *data TSRMLS_DC) /* {{{ */ */ int phar_flush(phar_archive_data *phar, char *user_stub, long len, char **error TSRMLS_DC) /* {{{ */ { - static const char newstub[] = "<?php __HALT_COMPILER(); ?>\r\n"; +#include "stub.h" +/* static const char newstub[] = "<?php __HALT_COMPILER(); ?>\r\n"; */ phar_entry_info *entry, *newentry; int halt_offset, restore_alias_len, global_flags = 0, closeoldfile; char *buf, *pos; @@ -3199,12 +3200,12 @@ PHP_MINIT_FUNCTION(phar) /* {{{ */ phar_has_bz2 = zend_hash_exists(&module_registry, "bz2", sizeof("bz2")); phar_has_zlib = zend_hash_exists(&module_registry, "zlib", sizeof("zlib")); if (SUCCESS == zend_hash_find(&module_registry, "zip", sizeof("zip"), (void **) &test)) { - if (strlen(test->version) == sizeof("1.8.11")-1 && !strncmp(test->version, "1.8.11", sizeof("1.8.11")-1)) { + if (php_version_compare((const char *) test->version, "1.8.11") != -1) { phar_has_zip = 1; } else { phar_has_zip = 0; } - phar_zip_ver = test->version; + phar_zip_ver = (char *) test->version; } else { phar_has_zip = 0; phar_zip_ver = NULL; diff --git a/ext/phar/phar_internal.h b/ext/phar/phar_internal.h index 4fc713ae46..82a60d9674 100755 --- a/ext/phar/phar_internal.h +++ b/ext/phar/phar_internal.h @@ -54,6 +54,7 @@ #include "ext/standard/sha1.h" #include "ext/standard/php_var.h" #include "ext/standard/php_smart_str.h" +#include "ext/standard/php_versioning.h" #ifndef PHP_WIN32 #include "TSRM/tsrm_strtok_r.h" #endif diff --git a/ext/phar/shortarc.php b/ext/phar/shortarc.php new file mode 100644 index 0000000000..5ab57577a3 --- /dev/null +++ b/ext/phar/shortarc.php @@ -0,0 +1,176 @@ +<?php +if (in_array('phar', stream_get_wrappers()) && class_exists('Phar', 0)) { + Phar::interceptFileFuncs(); + include 'phar://' . __FILE__ . '/index.php'; + return; +} +class Extract_Phar +{ + static $tmp = array(); + static $origdir; + const GZ = 0x1000; + const BZ2 = 0x2000; + const MASK = 0x3000; + static function go($D) + { + register_shutdown_function(array('Extract_Phar', '_removeTmpFiles')); + $fp = fopen(__FILE__, 'rb'); + fseek($fp, $D); + $L = unpack('V', fread($fp, 4)); + $m = ''; + do { + $read = 8192; + if ($L[1] - strlen($m) < 8192) { + $read = $L[1] - strlen($m); + } + $last = fread($fp, $read); + $m .= $last; + } while (strlen($last) && strlen($m) < $L[1]); + if (strlen($m) < $L[1]) { + die('ERROR: manifest length read was "' . + strlen($m) .'" should be "' . + $L[1] . '"'); + } + $info = self::_unpack($m); + $f = $info['c']; + if ($f & self::GZ) { + if (!function_exists('gzinflate')) { + die('Error: zlib extension is not enabled - gzinflate() function needed' . + ' for compressed .phars'); + } + } + if ($f & self::BZ2) { + if (!function_exists('bzdecompress')) { + die('Error: bzip2 extension is not enabled - bzdecompress() function needed' . + ' for compressed .phars'); + } + } + $temp = self::tmpdir(); + if (!$temp) { + $sessionpath = session_save_path(); + if (strpos ($sessionpath, ";") !== FALSE) + $sessionpath = substr ($sessionpath, strpos ($sessionpath, ";")+1); + if (!file_exists($sessionpath) && !is_dir($sessionpath)) { + die('Could not locate temporary directory to extract phar'); + } + $temp = $sessionpath; + } + $temp .= '/pharextract'; + if (!file_exists($temp)) { + @mkdir($temp); + $temp = realpath($temp); + self::$tmp[] = $temp; + } + self::$origdir = getcwd(); + foreach ($info['m'] as $path => $file) { + $a = !file_exists(dirname($temp . '/' . $path)); + @mkdir(dirname($temp . '/' . $path), 0777, true); + clearstatcache(); + if ($a) self::$tmp[] = realpath(dirname($temp . '/' . $path)); + if ($path[strlen($path) - 1] == '/') { + mkdir($temp . '/' . $path); + } else { + file_put_contents($temp . '/' . $path, self::extractFile($path, $file, $fp)); + } + self::$tmp[] = realpath($temp . '/' . $path); + } + chdir($temp); + include 'index.php'; + } + + static function tmpdir() + { + if (strpos(PHP_OS, 'WIN') !== false) { + if ($var = isset($_ENV['TMP']) ? $_ENV['TMP'] : getenv('TMP')) { + return $var; + } + if ($var = isset($_ENV['TEMP']) ? $_ENV['TEMP'] : getenv('TEMP')) { + return $var; + } + if ($var = isset($_ENV['USERPROFILE']) ? $_ENV['USERPROFILE'] : @getenv('USERPROFILE')) { + return $var; + } + if ($var = isset($_ENV['windir']) ? $_ENV['windir'] : getenv('windir')) { + return $var; + } + return @getenv('SystemRoot') . '\temp'; + } + if ($var = isset($_ENV['TMPDIR']) ? $_ENV['TMPDIR'] : getenv('TMPDIR')) { + return $var; + } + return realpath('/tmp'); + } + + static function _unpack($m) + { + $info = unpack('V', substr($m, 0, 4)); + // skip API version, phar flags, alias, metadata + $l = unpack('V', substr($m, 10, 4)); + $m = substr($m, 14 + $l[1]); + $s = unpack('V', substr($m, 0, 4)); + $o = 0; + $start = 4 + $s[1]; + $ret['c'] = 0; + for ($i = 0; $i < $info[1]; $i++) { + // length of the file name + $len = unpack('V', substr($m, $start, 4)); + $start += 4; + // file name + $savepath = substr($m, $start, $len[1]); + $start += $len[1]; + // retrieve manifest data: + // 0 = size, 1 = timestamp, 2 = compressed size, 3 = crc32, 4 = flags + // 5 = metadata length + $ret['m'][$savepath] = array_values(unpack('Va/Vb/Vc/Vd/Ve/Vf', substr($m, $start, 24))); + $ret['m'][$savepath][3] = sprintf('%u', $ret['m'][$savepath][3] + & 0xffffffff); + $ret['m'][$savepath][7] = $o; + $o += $ret['m'][$savepath][2]; + $start += 24 + $ret['m'][$savepath][5]; + $ret['c'] |= $ret['m'][$savepath][4] & self::MASK; + } + return $ret; + } + + static function extractFile($path, $entry, $fp) + { + $data = ''; + $c = $entry[2]; + while ($c) { + if ($c < 8192) { + $data .= @fread($fp, $c); + $c = 0; + } else { + $c -= 8192; + $data .= @fread($fp, 8192); + } + } + if ($entry[4] & self::GZ) { + $data = gzinflate($data); + } elseif ($entry[4] & self::BZ2) { + $data = bzdecompress($data); + } + if (strlen($data) != $entry[0]) { + die("Not valid internal .phar file (size error " . strlen($data) . " != " . + $stat[7] . ")"); + } + if ($entry[3] != sprintf("%u", crc32($data) & 0xffffffff)) { + die("Not valid internal .phar file (checksum error)"); + } + return $data; + } + + static function _removeTmpFiles() + { + // for removal of temp files + usort(self::$tmp, 'strnatcasecmp'); + array_reverse(self::$tmp, 1); + if (count(self::$tmp)) { + foreach (self::$tmp as $f) { + if (file_exists($f)) is_dir($f) ? @rmdir($f) : @unlink($f); + } + + } + chdir(self::$origdir); + } +}
\ No newline at end of file diff --git a/ext/phar/stream.c b/ext/phar/stream.c index ef0bdf0f5b..cf24b5045d 100644 --- a/ext/phar/stream.c +++ b/ext/phar/stream.c @@ -65,7 +65,9 @@ php_url* phar_open_url(php_stream_wrapper *wrapper, char *filename, char *mode, if (!strncasecmp(filename, "phar://", 7)) { if (mode[0] == 'a') { - php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: open mode append not supported"); + if (!(options & PHP_STREAM_URL_STAT_QUIET)) { + php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: open mode append not supported"); + } return NULL; } if (phar_split_fname(filename, strlen(filename), &arch, &arch_len, &entry, &entry_len TSRMLS_CC) == FAILURE) { @@ -108,14 +110,18 @@ php_url* phar_open_url(php_stream_wrapper *wrapper, char *filename, char *mode, } if (mode[0] == 'w' || (mode[0] == 'r' && mode[1] == '+')) { if (PHAR_G(readonly)) { - php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: write operations disabled by INI setting"); + if (!(options & PHP_STREAM_URL_STAT_QUIET)) { + php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: write operations disabled by INI setting"); + } php_url_free(resource); return NULL; } if (phar_open_or_create_filename(resource->host, arch_len, NULL, 0, options, NULL, &error TSRMLS_CC) == FAILURE) { if (error) { - php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, error); + if (!(options & PHP_STREAM_URL_STAT_QUIET)) { + php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, error); + } efree(error); } php_url_free(resource); @@ -125,7 +131,9 @@ php_url* phar_open_url(php_stream_wrapper *wrapper, char *filename, char *mode, if (phar_open_filename(resource->host, arch_len, NULL, 0, options, NULL, &error TSRMLS_CC) == FAILURE) { if (error) { - php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, error); + if (!(options & PHP_STREAM_URL_STAT_QUIET)) { + php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, error); + } efree(error); } php_url_free(resource); diff --git a/ext/phar/stub.h b/ext/phar/stub.h new file mode 100644 index 0000000000..7f42a99f9c --- /dev/null +++ b/ext/phar/stub.h @@ -0,0 +1,21 @@ +/* + +----------------------------------------------------------------------+ + | phar php single-file executable PHP extension generated stub | + +----------------------------------------------------------------------+ + | Copyright (c) 2005-2008 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt. | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Gregory Beaver <cellog@php.net> | + +----------------------------------------------------------------------+ +*/ + +/* $Id$ */ + +static const char newstub[] = "<?php\nif (in_array('phar', stream_get_wrappers()) && class_exists('Phar', 0)) {\nPhar::interceptFileFuncs();\ninclude 'phar://' . __FILE__ . '/index.php';\nreturn;\n}\nclass Extract_Phar\n{\nstatic $tmp = array();\nstatic $origdir;\nconst GZ = 0x1000;\nconst BZ2 = 0x2000;\nconst MASK = 0x3000;\nstatic function go($D)\n{\nregister_shutdown_function(array('Extract_Phar', '_removeTmpFiles'));\n$fp = fopen(__FILE__, 'rb');\nfseek($fp, $D);\n$L = unpack('V', fread($fp, 4));\n$m = '';\ndo {\n$read = 8192;\nif ($L[1] - strlen($m) < 8192) {\n$read = $L[1] - strlen($m);\n}\n$last = fread($fp, $read);\n$m .= $last;\n} while (strlen($last) && strlen($m) < $L[1]);\nif (strlen($m) < $L[1]) {\ndie('ERROR: manifest length read was \"' .\nstrlen($m) .'\" should be \"' .\n$L[1] . '\"');\n}\n$info = self::_unpack($m);\n$f = $info['c'];\nif ($f & self::GZ) {\nif (!function_exists('gzinflate')) {\ndie('Error: zlib extension is not enabled - gzinflate() function needed' .\n' for compressed .phars');\n}\n}\nif ($f & self::BZ2) {\nif (!function_exists('bzdecompress')) {\ndie('Error: bzip2 extension is not enabled - bzdecompress() function needed' .\n' for compressed .phars');\n}\n}\n$temp = self::tmpdir();\nif (!$temp) {\n$sessionpath = session_save_path();\nif (strpos ($sessionpath, \";\") !== FALSE)\n$sessionpath = substr ($sessionpath, strpos ($sessionpath, \";\")+1);\nif (!file_exists($sessionpath) && !is_dir($sessionpath)) {\ndie('Could not locate temporary directory to extract phar');\n}\n$temp = $sessionpath;\n}\n$temp .= '/pharextract';\nif (!file_exists($temp)) {\n@mkdir($temp);\n$temp = realpath($temp);\nself::$tmp[] = $temp;\n}\nself::$origdir = getcwd();\nforeach ($info['m'] as $path => $file) {\n$a = !file_exists(dirname($temp . '/' . $path));\n@mkdir(dirname($temp . '/' . $path), 0777, true);\nclearstatcache();\nif ($a) self::$tmp[] = realpath(dirname($temp . '/' . $path));\nif ($path[strlen($path) - 1] == '/') {\nmkdir($temp . '/' . $path);\n} else {\nfile_put_contents($temp . '/' . $path, self::extractFile($path, $file, $fp));\n}\nself::$tmp[] = realpath($temp . '/' . $path);\n}\nchdir($temp);\ninclude 'index.php';\n}\n\nstatic function tmpdir()\n{\nif (strpos(PHP_OS, 'WIN') !== false) {\nif ($var = isset($_ENV['TMP']) ? $_ENV['TMP'] : getenv('TMP')) {\nreturn $var;\n}\nif ($var = isset($_ENV['TEMP']) ? $_ENV['TEMP'] : getenv('TEMP')) {\nreturn $var;\n}\nif ($var = isset($_ENV['USERPROFILE']) ? $_ENV['USERPROFILE'] : @getenv('USERPROFILE')) {\nreturn $var;\n}\nif ($var = isset($_ENV['windir']) ? $_ENV['windir'] : getenv('windir')) {\nreturn $var;\n}\nreturn @getenv('SystemRoot') . '\temp';\n}\nif ($var = isset($_ENV['TMPDIR']) ? $_ENV['TMPDIR'] : getenv('TMPDIR')) {\nreturn $var;\n}\nreturn realpath('/tmp');\n}\n\nstatic function _unpack($m)\n{\n$info = unpack('V', substr($m, 0, 4));\n// skip API version, phar flags, alias, metadata\n$l = unpack('V', substr($m, 10, 4));\n$m = substr($m, 14 + $l[1]);\n$s = unpack('V', substr($m, 0, 4));\n$o = 0;\n$start = 4 + $s[1];\n$ret['c'] = 0;\nfor ($i = 0; $i < $info[1]; $i++) {\n// length of the file name\n$len = unpack('V', substr($m, $start, 4));\n$start += 4;\n// file name\n$savepath = substr($m, $start, $len[1]);\n$start += $len[1];\n// retrieve manifest data:\n// 0 = size, 1 = timestamp, 2 = compressed size, 3 = crc32, 4 = flags\n// 5 = metadata length\n$ret['m'][$savepath] = array_values(unpack('Va/Vb/Vc/Vd/Ve/Vf', substr($m, $start, 24)));\n$ret['m'][$savepath][3] = sprintf('%u', $ret['m'][$savepath][3]\n& 0xffffffff);\n$ret['m'][$savepath][7] = $o;\n$o += $ret['m'][$savepath][2];\n$start += 24 + $ret['m'][$savepath][5];\n$ret['c'] |= $ret['m'][$savepath][4] & self::MASK;\n}\nreturn $ret;\n}\n\nstatic function extractFile($path, $entry, $fp)\n{\n$data = '';\n$c = $entry[2];\nwhile ($c) {\nif ($c < 8192) {\n$data .= @fread($fp, $c);\n$c = 0;\n} else {\n$c -= 8192;\n$data .= @fread($fp, 8192);\n}\n}\nif ($entry[4] & self::GZ) {\n$data = gzinflate($data);\n} elseif ($entry[4] & self::BZ2) {\n$data = bzdecompress($data);\n}\nif (strlen($data) != $entry[0]) {\ndie(\"Not valid internal .phar file (size error \" . strlen($data) . \" != \" .\n$stat[7] . \")\");\n}\nif ($entry[3] != sprintf(\"%u\", crc32($data) & 0xffffffff)) {\ndie(\"Not valid internal .phar file (checksum error)\");\n}\nreturn $data;\n}\n\nstatic function _removeTmpFiles()\n{\n// for removal of temp files\nusort(self::$tmp, 'strnatcasecmp');\narray_reverse(self::$tmp, 1);\nif (count(self::$tmp)) {\nforeach (self::$tmp as $f) {\nif (file_exists($f)) is_dir($f) ? @rmdir($f) : @unlink($f);\n}\n\n}\nchdir(self::$origdir);\n}\n}\nExtract_Phar::go(4461);\n__HALT_COMPILER(); ?>"; diff --git a/ext/phar/tests/nophar.phar b/ext/phar/tests/nophar.phar Binary files differnew file mode 100644 index 0000000000..e3235b28f6 --- /dev/null +++ b/ext/phar/tests/nophar.phar diff --git a/ext/phar/tests/nophar.phar.inc b/ext/phar/tests/nophar.phar.inc new file mode 100644 index 0000000000..78867f1a8c --- /dev/null +++ b/ext/phar/tests/nophar.phar.inc @@ -0,0 +1,8 @@ +<?php +$fname = dirname(__FILE__) . '/nophar.phar'; +@unlink($fname); +$p = new Phar($fname); +$p['index.php'] = '<?php include "b/c.php";' . "\n"; +$p['b/c.php'] = '<?php echo "in b\n";$a = fopen("index.php", "r", true);echo stream_get_contents($a);fclose($a);include dirname(__FILE__) . "/../d";'; +$p['d'] = "in d\n"; +?>
\ No newline at end of file diff --git a/ext/phar/tests/nophar.phpt b/ext/phar/tests/nophar.phpt new file mode 100644 index 0000000000..2b7af7ac63 --- /dev/null +++ b/ext/phar/tests/nophar.phpt @@ -0,0 +1,14 @@ +--TEST-- +Phar: phar run without pecl/phar with default stub +--SKIPIF-- +<?php if (extension_loaded("phar")) die("skip"); ?> +--FILE-- +<?php +include dirname(__FILE__) . '/nophar.phar'; +?> +===DONE=== +--EXPECT-- +in b +<?php include "b/c.php"; +in d +===DONE=== diff --git a/ext/phar/tests/phar_commitwrite.phpt b/ext/phar/tests/phar_commitwrite.phpt index 8a68e8e5c6..b1ad5cffda 100644 --- a/ext/phar/tests/phar_commitwrite.phpt +++ b/ext/phar/tests/phar_commitwrite.phpt @@ -26,10 +26,187 @@ var_dump($p->getStub()); --CLEAN-- <?php unlink(dirname(__FILE__) . '/brandnewphar.phar'); +__HALT_COMPILER(); ?> --EXPECT-- -string(29) "<?php __HALT_COMPILER(); ?> -" +string(4461) "<?php +if (in_array('phar', stream_get_wrappers()) && class_exists('Phar', 0)) { +Phar::interceptFileFuncs(); +include 'phar://' . __FILE__ . '/index.php'; +return; +} +class Extract_Phar +{ +static $tmp = array(); +static $origdir; +const GZ = 0x1000; +const BZ2 = 0x2000; +const MASK = 0x3000; +static function go($D) +{ +register_shutdown_function(array('Extract_Phar', '_removeTmpFiles')); +$fp = fopen(__FILE__, 'rb'); +fseek($fp, $D); +$L = unpack('V', fread($fp, 4)); +$m = ''; +do { +$read = 8192; +if ($L[1] - strlen($m) < 8192) { +$read = $L[1] - strlen($m); +} +$last = fread($fp, $read); +$m .= $last; +} while (strlen($last) && strlen($m) < $L[1]); +if (strlen($m) < $L[1]) { +die('ERROR: manifest length read was "' . +strlen($m) .'" should be "' . +$L[1] . '"'); +} +$info = self::_unpack($m); +$f = $info['c']; +if ($f & self::GZ) { +if (!function_exists('gzinflate')) { +die('Error: zlib extension is not enabled - gzinflate() function needed' . +' for compressed .phars'); +} +} +if ($f & self::BZ2) { +if (!function_exists('bzdecompress')) { +die('Error: bzip2 extension is not enabled - bzdecompress() function needed' . +' for compressed .phars'); +} +} +$temp = self::tmpdir(); +if (!$temp) { +$sessionpath = session_save_path(); +if (strpos ($sessionpath, ";") !== FALSE) +$sessionpath = substr ($sessionpath, strpos ($sessionpath, ";")+1); +if (!file_exists($sessionpath) && !is_dir($sessionpath)) { +die('Could not locate temporary directory to extract phar'); +} +$temp = $sessionpath; +} +$temp .= '/pharextract'; +if (!file_exists($temp)) { +@mkdir($temp); +$temp = realpath($temp); +self::$tmp[] = $temp; +} +self::$origdir = getcwd(); +foreach ($info['m'] as $path => $file) { +$a = !file_exists(dirname($temp . '/' . $path)); +@mkdir(dirname($temp . '/' . $path), 0777, true); +clearstatcache(); +if ($a) self::$tmp[] = realpath(dirname($temp . '/' . $path)); +if ($path[strlen($path) - 1] == '/') { +mkdir($temp . '/' . $path); +} else { +file_put_contents($temp . '/' . $path, self::extractFile($path, $file, $fp)); +} +self::$tmp[] = realpath($temp . '/' . $path); +} +chdir($temp); +include 'index.php'; +} + +static function tmpdir() +{ +if (strpos(PHP_OS, 'WIN') !== false) { +if ($var = isset($_ENV['TMP']) ? $_ENV['TMP'] : getenv('TMP')) { +return $var; +} +if ($var = isset($_ENV['TEMP']) ? $_ENV['TEMP'] : getenv('TEMP')) { +return $var; +} +if ($var = isset($_ENV['USERPROFILE']) ? $_ENV['USERPROFILE'] : @getenv('USERPROFILE')) { +return $var; +} +if ($var = isset($_ENV['windir']) ? $_ENV['windir'] : getenv('windir')) { +return $var; +} +return @getenv('SystemRoot') . ' emp'; +} +if ($var = isset($_ENV['TMPDIR']) ? $_ENV['TMPDIR'] : getenv('TMPDIR')) { +return $var; +} +return realpath('/tmp'); +} + +static function _unpack($m) +{ +$info = unpack('V', substr($m, 0, 4)); +// skip API version, phar flags, alias, metadata +$l = unpack('V', substr($m, 10, 4)); +$m = substr($m, 14 + $l[1]); +$s = unpack('V', substr($m, 0, 4)); +$o = 0; +$start = 4 + $s[1]; +$ret['c'] = 0; +for ($i = 0; $i < $info[1]; $i++) { +// length of the file name +$len = unpack('V', substr($m, $start, 4)); +$start += 4; +// file name +$savepath = substr($m, $start, $len[1]); +$start += $len[1]; +// retrieve manifest data: +// 0 = size, 1 = timestamp, 2 = compressed size, 3 = crc32, 4 = flags +// 5 = metadata length +$ret['m'][$savepath] = array_values(unpack('Va/Vb/Vc/Vd/Ve/Vf', substr($m, $start, 24))); +$ret['m'][$savepath][3] = sprintf('%u', $ret['m'][$savepath][3] +& 0xffffffff); +$ret['m'][$savepath][7] = $o; +$o += $ret['m'][$savepath][2]; +$start += 24 + $ret['m'][$savepath][5]; +$ret['c'] |= $ret['m'][$savepath][4] & self::MASK; +} +return $ret; +} + +static function extractFile($path, $entry, $fp) +{ +$data = ''; +$c = $entry[2]; +while ($c) { +if ($c < 8192) { +$data .= @fread($fp, $c); +$c = 0; +} else { +$c -= 8192; +$data .= @fread($fp, 8192); +} +} +if ($entry[4] & self::GZ) { +$data = gzinflate($data); +} elseif ($entry[4] & self::BZ2) { +$data = bzdecompress($data); +} +if (strlen($data) != $entry[0]) { +die("Not valid internal .phar file (size error " . strlen($data) . " != " . +$stat[7] . ")"); +} +if ($entry[3] != sprintf("%u", crc32($data) & 0xffffffff)) { +die("Not valid internal .phar file (checksum error)"); +} +return $data; +} + +static function _removeTmpFiles() +{ +// for removal of temp files +usort(self::$tmp, 'strnatcasecmp'); +array_reverse(self::$tmp, 1); +if (count(self::$tmp)) { +foreach (self::$tmp as $f) { +if (file_exists($f)) is_dir($f) ? @rmdir($f) : @unlink($f); +} + +} +chdir(self::$origdir); +} +} +Extract_Phar::go(4433); +__HALT_COMPILER(); ?>" string(200) "<?php function __autoload($class) { diff --git a/ext/phar/tests/phar_create_in_cwd.phpt b/ext/phar/tests/phar_create_in_cwd.phpt index 6308254810..86a211df1d 100644 --- a/ext/phar/tests/phar_create_in_cwd.phpt +++ b/ext/phar/tests/phar_create_in_cwd.phpt @@ -11,7 +11,7 @@ chdir(dirname(__FILE__)); try { $p = new Phar('brandnewphar.phar'); $p['file1.txt'] = 'hi'; - var_dump($p->getStub()); + var_dump(strlen($p->getStub())); $p->setStub("<?php function __autoload(\$class) { @@ -32,8 +32,7 @@ __HALT_COMPILER(); unlink(dirname(__FILE__) . '/brandnewphar.phar'); ?> --EXPECT-- -string(29) "<?php __HALT_COMPILER(); ?> -" +int(4461) string(200) "<?php function __autoload($class) { diff --git a/ext/phar/tests/withphar.phpt b/ext/phar/tests/withphar.phpt new file mode 100644 index 0000000000..b4c95e86c1 --- /dev/null +++ b/ext/phar/tests/withphar.phpt @@ -0,0 +1,14 @@ +--TEST-- +Phar: phar run with pecl/phar with default stub +--SKIPIF-- +<?php if (!extension_loaded("phar")) die("skip"); ?> +--FILE-- +<?php +include dirname(__FILE__) . '/nophar.phar'; +?> +===DONE=== +--EXPECT-- +in b +<?php include "b/c.php"; +in d +===DONE=== |
