diff options
author | Dmitry Stogov <dmitry@php.net> | 2008-07-10 11:36:50 +0000 |
---|---|---|
committer | Dmitry Stogov <dmitry@php.net> | 2008-07-10 11:36:50 +0000 |
commit | 53bbf1238cd3f19c3f869f1a01704cdbab60c712 (patch) | |
tree | 10d70300a9aba5e343c85537e51d6b87ba7eb440 /ext/phar/func_interceptors.c | |
parent | 8ceb0b6fd36b4a228a15d97ec01361589d4834da (diff) | |
download | php-git-53bbf1238cd3f19c3f869f1a01704cdbab60c712.tar.gz |
Extensions MUST NOT manipulate with internal functions from EG(function_table) in run-time. It may cause problems with opcode caches and in multi-threaded environment. Now the same functions are overriden at MINIT and call original functions or PHAR ones dependent on flag setting.
Diffstat (limited to 'ext/phar/func_interceptors.c')
-rw-r--r-- | ext/phar/func_interceptors.c | 77 |
1 files changed, 60 insertions, 17 deletions
diff --git a/ext/phar/func_interceptors.c b/ext/phar/func_interceptors.c index 81d3ec710b..08cdcc18b1 100644 --- a/ext/phar/func_interceptors.c +++ b/ext/phar/func_interceptors.c @@ -29,6 +29,10 @@ PHAR_FUNC(phar_opendir) /* {{{ */ int filename_len; zval *zcontext = NULL; + if (!PHAR_G(intercepted)) { + goto skip_phar; + } + if ((PHAR_GLOBALS->phar_fname_map.arBuckets && !zend_hash_num_elements(&(PHAR_GLOBALS->phar_fname_map))) && !cached_phars.arBuckets) { goto skip_phar; @@ -98,6 +102,10 @@ PHAR_FUNC(phar_file_get_contents) /* {{{ */ long maxlen = PHP_STREAM_COPY_ALL; zval *zcontext = NULL; + if (!PHAR_G(intercepted)) { + goto skip_phar; + } + if ((PHAR_GLOBALS->phar_fname_map.arBuckets && !zend_hash_num_elements(&(PHAR_GLOBALS->phar_fname_map))) && !cached_phars.arBuckets) { goto skip_phar; @@ -224,6 +232,10 @@ PHAR_FUNC(phar_readfile) /* {{{ */ zval *zcontext = NULL; php_stream *stream; + if (!PHAR_G(intercepted)) { + goto skip_phar; + } + if ((PHAR_GLOBALS->phar_fname_map.arBuckets && !zend_hash_num_elements(&(PHAR_GLOBALS->phar_fname_map))) && !cached_phars.arBuckets) { goto skip_phar; @@ -315,6 +327,10 @@ PHAR_FUNC(phar_fopen) /* {{{ */ zval *zcontext = NULL; php_stream *stream; + if (!PHAR_G(intercepted)) { + goto skip_phar; + } + if ((PHAR_GLOBALS->phar_fname_map.arBuckets && !zend_hash_num_elements(&(PHAR_GLOBALS->phar_fname_map))) && !cached_phars.arBuckets) { /* no need to check, include_path not even specified in fopen/ no active phars */ @@ -792,14 +808,18 @@ skip_phar: #define PharFileFunction(fname, funcnum, orig) \ void fname(INTERNAL_FUNCTION_PARAMETERS) { \ - char *filename; \ - int filename_len; \ - \ - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &filename, &filename_len) == FAILURE) { \ - return; \ + if (!PHAR_G(intercepted)) { \ + PHAR_G(orig)(INTERNAL_FUNCTION_PARAM_PASSTHRU); \ + } else { \ + char *filename; \ + int filename_len; \ + \ + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &filename, &filename_len) == FAILURE) { \ + return; \ + } \ + \ + phar_file_stat(filename, (php_stat_len) filename_len, funcnum, PHAR_G(orig), INTERNAL_FUNCTION_PARAM_PASSTHRU); \ } \ - \ - phar_file_stat(filename, (php_stat_len) filename_len, funcnum, PHAR_G(orig), INTERNAL_FUNCTION_PARAM_PASSTHRU); \ } /* }}} */ @@ -878,6 +898,10 @@ PHAR_FUNC(phar_is_file) /* {{{ */ char *filename; int filename_len; + if (!PHAR_G(intercepted)) { + goto skip_phar; + } + if ((PHAR_GLOBALS->phar_fname_map.arBuckets && !zend_hash_num_elements(&(PHAR_GLOBALS->phar_fname_map))) && !cached_phars.arBuckets) { goto skip_phar; @@ -939,6 +963,10 @@ PHAR_FUNC(phar_is_link) /* {{{ */ char *filename; int filename_len; + if (!PHAR_G(intercepted)) { + goto skip_phar; + } + if ((PHAR_GLOBALS->phar_fname_map.arBuckets && !zend_hash_num_elements(&(PHAR_GLOBALS->phar_fname_map))) && !cached_phars.arBuckets) { goto skip_phar; @@ -1006,6 +1034,26 @@ PharFileFunction(phar_stat, FS_STAT, orig_stat) /* }}} */ /* {{{ void phar_intercept_functions(TSRMLS_D) */ +void phar_intercept_functions(TSRMLS_D) +{ + zend_function *orig; + + if (!PHAR_G(request_init)) { + PHAR_G(cwd) = NULL; + PHAR_G(cwd_len) = 0; + } + PHAR_G(intercepted) = 1; +} +/* }}} */ + +/* {{{ void phar_release_functions(TSRMLS_D) */ +void phar_release_functions(TSRMLS_D) +{ + PHAR_G(intercepted) = 0; +} +/* }}} */ + +/* {{{ void phar_intercept_functions_init(TSRMLS_D) */ #define PHAR_INTERCEPT(func) \ PHAR_G(orig_##func) = NULL; \ if (SUCCESS == zend_hash_find(CG(function_table), #func, sizeof(#func), (void **)&orig)) { \ @@ -1013,17 +1061,10 @@ PharFileFunction(phar_stat, FS_STAT, orig_stat) orig->internal_function.handler = phar_##func; \ } -void phar_intercept_functions(TSRMLS_D) +void phar_intercept_functions_init(TSRMLS_D) { zend_function *orig; - if (!PHAR_G(request_init)) { - PHAR_G(cwd) = NULL; - PHAR_G(cwd_len) = 0; - } else if (PHAR_G(orig_fopen)) { - /* don't double-intercept */ - return; - } PHAR_INTERCEPT(fopen); PHAR_INTERCEPT(file_get_contents); PHAR_INTERCEPT(is_file); @@ -1046,17 +1087,18 @@ void phar_intercept_functions(TSRMLS_D) PHAR_INTERCEPT(lstat); PHAR_INTERCEPT(stat); PHAR_INTERCEPT(readfile); + PHAR_G(intercepted) = 0; } /* }}} */ -/* {{{ void phar_release_functions(TSRMLS_D) */ +/* {{{ void phar_intercept_functions_shutdown(TSRMLS_D) */ #define PHAR_RELEASE(func) \ if (PHAR_G(orig_##func) && SUCCESS == zend_hash_find(CG(function_table), #func, sizeof(#func), (void **)&orig)) { \ orig->internal_function.handler = PHAR_G(orig_##func); \ } \ PHAR_G(orig_##func) = NULL; -void phar_release_functions(TSRMLS_D) +void phar_intercept_functions_shutdown(TSRMLS_D) { zend_function *orig; @@ -1081,6 +1123,7 @@ void phar_release_functions(TSRMLS_D) PHAR_RELEASE(lstat); PHAR_RELEASE(stat); PHAR_RELEASE(readfile); + PHAR_G(intercepted) = 0; } /* }}} */ |