From: Greg Beaver Date: Tue, 18 Dec 2007 17:01:24 +0000 (+0000) Subject: [unfinished] magically handle getcwd() and fopen() with include_path inside phar X-Git-Tag: RELEASE_2_0_0a1~1139 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=0c51d581389cc6b62964e9057b893e72d9b55635;p=php [unfinished] magically handle getcwd() and fopen() with include_path inside phar this work is incomplete, but compiles and existing tests pass --- diff --git a/ext/phar/phar.c b/ext/phar/phar.c index 9740a7f978..5bb738b344 100644 --- a/ext/phar/phar.c +++ b/ext/phar/phar.c @@ -1254,7 +1254,7 @@ int phar_open_file(php_stream *fp, char *fname, int fname_len, char *alias, int efree(entry.filename); MAPPHAR_FAIL("zlib extension is required for gz compressed .phar file \"%s\""); #else - if (!PHAR_G(has_zlib)) { + if (!phar_has_zlib) { if (entry.metadata) { zval_ptr_dtor(&entry.metadata); } @@ -1271,7 +1271,7 @@ int phar_open_file(php_stream *fp, char *fname, int fname_len, char *alias, int efree(entry.filename); MAPPHAR_FAIL("bz2 extension is required for bzip2 compressed .phar file \"%s\""); #else - if (!PHAR_G(has_bz2)) { + if (!phar_has_bz2) { if (entry.metadata) { zval_ptr_dtor(&entry.metadata); } @@ -3753,7 +3753,7 @@ static zend_op_array *phar_compile_file(zend_file_handle *file_handle, int type zend_op_array *(*save)(zend_file_handle *file_handle, int type TSRMLS_DC); save = zend_compile_file; /* restore current handler or we cause trouble */ - zend_compile_file = PHAR_G(orig_compile_file); + zend_compile_file = phar_orig_compile_file; if (zend_hash_num_elements(&(PHAR_GLOBALS->phar_fname_map))) { char *arch, *entry; int arch_len, entry_len; @@ -3790,16 +3790,91 @@ skip_phar: } /* }}} */ +static void phar_fopen(INTERNAL_FUNCTION_PARAMETERS) +{ + char *filename, *mode; + int filename_len, mode_len; + zend_bool use_include_path = 0; + zval *zcontext = NULL; + php_stream *stream; + + if (ht < 3 || !zend_hash_num_elements(&(PHAR_GLOBALS->phar_fname_map))) { + /* no need to check, include_path not even specified in fopen/ no active phars */ + goto skip_phar; + } + if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "ss|br", &filename, &filename_len, &mode, &mode_len, &use_include_path, &zcontext) == FAILURE || !use_include_path) { + goto skip_phar; + } + { + char *arch, *entry, *fname; + int arch_len, entry_len, fname_len; + fname = zend_get_executed_filename(TSRMLS_C); + if (strncasecmp(fname, "phar://", 7)) { + goto skip_phar; + } + fname_len = strlen(fname); + if (SUCCESS == phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, &entry_len TSRMLS_CC)) { + char *s, *name; + + efree(entry); + entry = filename; + /* include within phar, if :// is not in the url, then prepend phar:/// */ + entry_len = filename_len; + for (s = entry; s < (entry + entry_len - 4); s++) { + if (*s == ':' && *(s + 1) == '/' && *(s + 2) == '/') { + efree(arch); + goto skip_phar; + } + } + /* auto-convert to phar:// */ + spprintf(&name, 4096, "phar://%s/%s", arch, entry); + efree(arch); + stream = php_stream_open_wrapper(name, mode, 0, NULL); + efree(name); + php_stream_to_zval(stream, return_value); + return_value_used = 1; + return; + } + } +skip_phar: + return PHAR_G(orig_fopen)(INTERNAL_FUNCTION_PARAM_PASSTHRU); +} + +static void phar_getcwd(INTERNAL_FUNCTION_PARAMETERS) +{ + char *s, *fname; + int fname_len; + if (!zend_hash_num_elements(&(PHAR_GLOBALS->phar_fname_map))) { + /* no need to check, no active phars */ + goto skip_phar; + } + fname = zend_get_executed_filename(TSRMLS_C); + if (strncasecmp(fname, "phar://", 7)) { + goto skip_phar; + } + s = (char *) strrchr ((void *) fname, '/'); + fname_len = s-fname + 1; + fname = estrndup(s, fname_len); + fname[fname_len] = '\0'; + RETURN_STRINGL(fname, fname_len, 0); +skip_phar: + return PHAR_G(orig_getcwd)(INTERNAL_FUNCTION_PARAM_PASSTHRU); +} + PHP_MINIT_FUNCTION(phar) /* {{{ */ { ZEND_INIT_MODULE_GLOBALS(phar, php_phar_init_globals_module, NULL); REGISTER_INI_ENTRIES(); - PHAR_G(has_gnupg) = zend_hash_exists(&module_registry, "gnupg", sizeof("gnupg")); - PHAR_G(has_bz2) = zend_hash_exists(&module_registry, "bz2", sizeof("bz2")); - PHAR_G(has_zlib) = zend_hash_exists(&module_registry, "zlib", sizeof("zlib")); - PHAR_G(orig_compile_file) = zend_compile_file; + PHAR_G(orig_fopen) = NULL; + PHAR_G(orig_getcwd) = NULL; + phar_has_gnupg = zend_hash_exists(&module_registry, "gnupg", sizeof("gnupg")); + phar_has_bz2 = zend_hash_exists(&module_registry, "bz2", sizeof("bz2")); + phar_has_zlib = zend_hash_exists(&module_registry, "zlib", sizeof("zlib")); + + phar_orig_compile_file = zend_compile_file; zend_compile_file = phar_compile_file; + phar_object_init(TSRMLS_C); return php_register_url_stream_wrapper("phar", &php_stream_phar_wrapper TSRMLS_CC); @@ -3810,7 +3885,7 @@ PHP_MSHUTDOWN_FUNCTION(phar) /* {{{ */ { return php_unregister_url_stream_wrapper("phar" TSRMLS_CC); if (zend_compile_file == phar_compile_file) { - zend_compile_file = PHAR_G(orig_compile_file); + zend_compile_file = phar_orig_compile_file; } } /* }}} */ @@ -3819,6 +3894,7 @@ void phar_request_initialize(TSRMLS_D) /* {{{ */ { if (!PHAR_GLOBALS->request_init) { + zend_function *orig; PHAR_GLOBALS->request_init = 1; PHAR_GLOBALS->request_ends = 0; PHAR_GLOBALS->request_done = 0; @@ -3826,6 +3902,14 @@ void phar_request_initialize(TSRMLS_D) /* {{{ */ zend_hash_init(&(PHAR_GLOBALS->phar_alias_map), sizeof(phar_archive_data*), zend_get_hash_value, NULL, 0); zend_hash_init(&(PHAR_GLOBALS->phar_plain_map), sizeof(const char *), zend_get_hash_value, NULL, 0); phar_split_extract_list(TSRMLS_C); + if (PHAR_G(orig_fopen) && SUCCESS == zend_hash_find(EG(function_table), "fopen", 5, (void **)&orig)) { + PHAR_G(orig_fopen) = orig->internal_function.handler; + orig->internal_function.handler = phar_fopen; + } + if (SUCCESS == zend_hash_find(EG(function_table), "getcwd", 5, (void **)&orig)) { + PHAR_G(orig_getcwd) = orig->internal_function.handler; + orig->internal_function.handler = phar_getcwd; + } } } /* }}} */ @@ -3835,6 +3919,13 @@ PHP_RSHUTDOWN_FUNCTION(phar) /* {{{ */ PHAR_GLOBALS->request_ends = 1; if (PHAR_GLOBALS->request_init) { + zend_function *orig; + if (PHAR_G(orig_fopen) && SUCCESS == zend_hash_find(CG(function_table), "fopen", 5, (void **)&orig)) { + orig->internal_function.handler = PHAR_G(orig_fopen); + } + if (PHAR_G(orig_getcwd) && SUCCESS == zend_hash_find(CG(function_table), "getcwd", 5, (void **)&orig)) { + orig->internal_function.handler = PHAR_G(orig_getcwd); + } zend_hash_destroy(&(PHAR_GLOBALS->phar_alias_map)); zend_hash_destroy(&(PHAR_GLOBALS->phar_fname_map)); zend_hash_destroy(&(PHAR_GLOBALS->phar_plain_map)); @@ -3853,7 +3944,7 @@ PHP_MINFO_FUNCTION(phar) /* {{{ */ php_info_print_table_row(2, "Phar API version", PHAR_API_VERSION_STR); php_info_print_table_row(2, "CVS revision", "$Revision$"); #if HAVE_ZLIB - if (PHAR_G(has_zlib)) { + if (phar_has_zlib) { php_info_print_table_row(2, "gzip compression", "enabled"); } else { @@ -3865,7 +3956,7 @@ PHP_MINFO_FUNCTION(phar) /* {{{ */ "disabled"); #endif #if HAVE_BZ2 - if (PHAR_G(has_bz2)) { + if (phar_has_bz2 ) { php_info_print_table_row(2, "bzip2 compression", "disabled"); } else { @@ -3877,7 +3968,7 @@ PHP_MINFO_FUNCTION(phar) /* {{{ */ "disabled"); #endif #if HAVE_GNUPGLIB - if (PHAR_G(has_gnupg)) { + if (phar_has_gnupg) { php_info_print_table_row(2, "GPG signature", "enabled"); } else { diff --git a/ext/phar/phar_internal.h b/ext/phar/phar_internal.h index ada891eb6b..636fc551f3 100755 --- a/ext/phar/phar_internal.h +++ b/ext/phar/phar_internal.h @@ -34,6 +34,7 @@ #include "zend_operators.h" #include "zend_qsort.h" #include "main/php_streams.h" +#include "main/streams/php_stream_plain_wrapper.h" #include "ext/standard/info.h" #include "ext/standard/basic_functions.h" #include "ext/standard/url.h" @@ -114,14 +115,17 @@ ZEND_BEGIN_MODULE_GLOBALS(phar) int require_hash; int request_done; int request_ends; - int has_bz2:1; - int has_gnupg:1; - int has_zlib:1; - zend_op_array *(*orig_compile_file)(zend_file_handle *file_handle, int type TSRMLS_DC); + void (*orig_fopen)(INTERNAL_FUNCTION_PARAMETERS); + void (*orig_getcwd)(INTERNAL_FUNCTION_PARAMETERS); ZEND_END_MODULE_GLOBALS(phar) ZEND_EXTERN_MODULE_GLOBALS(phar) +int phar_has_bz2; +int phar_has_gnupg; +int phar_has_zlib; +zend_op_array *(*phar_orig_compile_file)(zend_file_handle *file_handle, int type TSRMLS_DC); + #ifdef ZTS # include "TSRM.h" # define PHAR_G(v) TSRMG(phar_globals_id, zend_phar_globals *, v) @@ -246,8 +250,12 @@ int phar_open_filename(char *fname, int fname_len, char *alias, int alias_len, i int phar_open_or_create_filename(char *fname, int fname_len, char *alias, int alias_len, int options, phar_archive_data** pphar, char **error TSRMLS_DC); int phar_open_compiled_file(char *alias, int alias_len, char **error TSRMLS_DC); -#ifdef PHAR_MAIN +static void phar_fopen(INTERNAL_FUNCTION_PARAMETERS); +static void phar_cwd(INTERNAL_FUNCTION_PARAMETERS); +#ifdef PHAR_MAIN +static void phar_fopen(INTERNAL_FUNCTION_PARAMETERS); +static void phar_getcwd(INTERNAL_FUNCTION_PARAMETERS); static int phar_open_fp(php_stream* fp, char *fname, int fname_len, char *alias, int alias_len, int options, phar_archive_data** pphar, char **error TSRMLS_DC); static php_url* phar_open_url(php_stream_wrapper *wrapper, char *filename, char *mode, int options TSRMLS_DC); diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c index 7e97fdc2b3..e7dfcb0fbf 100755 --- a/ext/phar/phar_object.c +++ b/ext/phar/phar_object.c @@ -144,7 +144,7 @@ PHP_METHOD(Phar, canCompress) switch (method) { case PHAR_ENT_COMPRESSED_GZ: #if HAVE_ZLIB - if (PHAR_G(has_zlib)) { + if (phar_has_zlib) { RETURN_TRUE; } else { RETURN_FALSE; @@ -155,7 +155,7 @@ PHP_METHOD(Phar, canCompress) case PHAR_ENT_COMPRESSED_BZ2: #if HAVE_BZ2 - if (PHAR_G(has_bz2)) { + if (phar_has_bz2) { RETURN_TRUE; } else { RETURN_FALSE; @@ -166,7 +166,7 @@ PHP_METHOD(Phar, canCompress) default: #if HAVE_ZLIB || HAVE_BZ2 - if (PHAR_G(has_zlib) || PHAR_G(has_bz2)) { + if (phar_has_zlib || phar_has_bz2) { RETURN_TRUE; } else { RETURN_FALSE; @@ -296,6 +296,42 @@ PHP_METHOD(Phar, __construct) } /* }}} */ +/* {{{ proto array Phar::getSupportedSignatures() + * Return array of supported signature types + */ +PHP_METHOD(Phar, getSupportedSignatures) +{ + array_init(return_value); + + add_next_index_stringl(return_value, "MD5", 3, 1); + add_next_index_stringl(return_value, "SHA-1", 5, 1); +#if HAVE_HASH_EXT + add_next_index_stringl(return_value, "SHA-256", 7, 1); + add_next_index_stringl(return_value, "SHA-512", 7, 1); +#endif +} +/* }}} */ + +/* {{{ proto array Phar::getSupportedCompression() + * Return array of supported comparession algorithms + */ +PHP_METHOD(Phar, getSupportedCompression) +{ + array_init(return_value); + +#if HAVE_ZLIB + if (phar_has_zlib) { + add_next_index_stringl(return_value, "GZ", 2, 1); + } +#endif +#if HAVE_BZ2 + if (phar_has_bz2) { + add_next_index_stringl(return_value, "BZIP2", 5, 1); + } +#endif +} +/* }}} */ + #if HAVE_SPL #define PHAR_ARCHIVE_OBJECT() \ @@ -820,42 +856,6 @@ PHP_METHOD(Phar, setSignatureAlgorithm) } /* }}} */ -/* {{{ proto array Phar::getSupportedSignatures() - * Return array of supported signature types - */ -PHP_METHOD(Phar, getSupportedSignatures) -{ - array_init(return_value); - - add_next_index_stringl(return_value, "MD5", 3, 1); - add_next_index_stringl(return_value, "SHA-1", 5, 1); -#if HAVE_HASH_EXT - add_next_index_stringl(return_value, "SHA-256", 7, 1); - add_next_index_stringl(return_value, "SHA-512", 7, 1); -#endif -} -/* }}} */ - -/* {{{ proto array Phar::getSupportedCompression() - * Return array of supported comparession algorithms - */ -PHP_METHOD(Phar, getSupportedCompression) -{ - array_init(return_value); - -#if HAVE_ZLIB - if (PHAR_G(has_zlib)) { - add_next_index_stringl(return_value, "GZ", 2, 1); - } -#endif -#if HAVE_BZ2 - if (PHAR_G(has_bz2)) { - add_next_index_stringl(return_value, "BZIP2", 5, 1); - } -#endif -} -/* }}} */ - /* {{{ proto array|false Phar::getSignature() * Return signature or false */ @@ -925,7 +925,7 @@ static int phar_test_compression(void *pDest, void *argument TSRMLS_DC) /* {{{ * *(int *) argument = 0; } #else - if (!PHAR_G(has_bz2)) { + if (!phar_has_bz2) { if (entry->flags & PHAR_ENT_COMPRESSED_BZ2) { *(int *) argument = 0; } @@ -936,7 +936,7 @@ static int phar_test_compression(void *pDest, void *argument TSRMLS_DC) /* {{{ * *(int *) argument = 0; } #else - if (!PHAR_G(has_zlib)) { + if (!phar_has_zlib) { if (entry->flags & PHAR_ENT_COMPRESSED_GZ) { *(int *) argument = 0; } @@ -976,7 +976,7 @@ PHP_METHOD(Phar, compressAllFilesGZ) "Phar is readonly, cannot change compression"); } #if HAVE_ZLIB - if (!PHAR_G(has_zlib)) { + if (!phar_has_zlib) { zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Cannot compress with Gzip compression, zlib extension is not enabled"); } @@ -1014,7 +1014,7 @@ PHP_METHOD(Phar, compressAllFilesBZIP2) "Phar is readonly, cannot change compression"); } #if HAVE_BZ2 - if (!PHAR_G(has_bz2)) { + if (!phar_has_bz2) { zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Cannot compress with Bzip2 compression, bz2 extension is not enabled"); } @@ -1756,7 +1756,7 @@ PHP_METHOD(PharFileInfo, setCompressedGZ) zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Cannot compress deleted file"); } - if (!PHAR_G(has_zlib)) { + if (!phar_has_zlib) { zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Cannot compress with Gzip compression, zlib extension is not enabled"); } @@ -1788,7 +1788,7 @@ PHP_METHOD(PharFileInfo, setCompressedBZIP2) char *error; PHAR_ENTRY_OBJECT(); - if (!PHAR_G(has_bz2)) { + if (!phar_has_bz2) { zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Cannot compress with Bzip2 compression, bz2 extension is not enabled"); } @@ -1858,7 +1858,7 @@ PHP_METHOD(PharFileInfo, setUncompressed) "Cannot uncompress Gzip-compressed file, zlib extension is not enabled"); } #else - if (!PHAR_G(has_zlib)) { + if (!phar_has_zlib) { zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Cannot uncompress Gzip-compressed file, zlib extension is not enabled"); } @@ -1869,7 +1869,7 @@ PHP_METHOD(PharFileInfo, setUncompressed) "Cannot uncompress Bzip2-compressed file, bzip2 extension is not enabled"); } #else - if (!PHAR_G(has_bz2)) { + if (!phar_has_bz2) { zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Cannot uncompress Bzip2-compressed file, bzip2 extension is not enabled"); } diff --git a/ext/phar/tests/phar_magic.phpt b/ext/phar/tests/phar_magic.phpt new file mode 100644 index 0000000000..adb3ad5c90 --- /dev/null +++ b/ext/phar/tests/phar_magic.phpt @@ -0,0 +1,21 @@ +--TEST-- +Phar::setStub() +--SKIPIF-- + +--INI-- +phar.require_hash=0 +phar.readonly=0 +--FILE-- + +===DONE=== +--CLEAN-- + +--EXPECT-- +===DONE===