From: George Wang Date: Mon, 29 Aug 2016 02:23:28 +0000 (-0400) Subject: Merge branch 'PHP-5.6' into PHP-7.0 X-Git-Tag: php-7.0.11RC1~22 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ca1eb585ee0ef7d2ab5bb4160aa0a36f59d51a48;p=php Merge branch 'PHP-5.6' into PHP-7.0 Conflicts: sapi/litespeed/lsapi_main.c --- ca1eb585ee0ef7d2ab5bb4160aa0a36f59d51a48 diff --cc sapi/litespeed/lsapi_main.c index b0ea105a88,d3d9682428..65d2451ab6 --- a/sapi/litespeed/lsapi_main.c +++ b/sapi/litespeed/lsapi_main.c @@@ -196,55 -221,70 +218,27 @@@ static char *sapi_lsapi_getenv( char * /* }}} */ - -#if PHP_MAJOR_VERSION > 4 -- static int add_variable( const char * pKey, int keyLen, const char * pValue, int valLen, - void * arg TSRMLS_DC) + void * arg ) { --#if PHP_MAJOR_VERSION >= 7 - int filter_arg = (Z_ARR_P((zval *)arg) == Z_ARR(PG(http_globals)[TRACK_VARS_ENV])) + int filter_arg = (Z_ARR_P((zval *)arg) == Z_ARR(PG(http_globals)[TRACK_VARS_ENV])) ? PARSE_ENV : PARSE_SERVER; - #else - int filter_arg = (arg == PG(http_globals)[TRACK_VARS_ENV])?PARSE_ENV:PARSE_SERVER; - #endif + char * new_val = (char *) pValue; size_t new_val_len; -#else - int filter_arg = (arg == PG(http_globals)[TRACK_VARS_ENV])?PARSE_ENV:PARSE_SERVER; - unsigned int new_val_len; -#endif - char * new_val = (char *) pValue; - - if (sapi_module.input_filter(filter_arg, (char *)pKey, &new_val, valLen, &new_val_len TSRMLS_CC)) { - php_register_variable_safe((char *)pKey, new_val, new_val_len, (zval *)arg TSRMLS_CC); + if (sapi_module.input_filter(filter_arg, (char *)pKey, &new_val, valLen, &new_val_len)) { + php_register_variable_safe((char *)pKey, new_val, new_val_len, (zval *)arg ); } - return 1; - } - - /* - static int add_variable( const char * pKey, int keyLen, const char * pValue, int valLen, - void * arg ) - { - zval * gpc_element, **gpc_element_p; - HashTable * symtable1 = Z_ARRVAL_P((zval * )arg); - register char * pKey1 = (char *)pKey; - - MAKE_STD_ZVAL(gpc_element); - Z_STRLEN_P( gpc_element ) = valLen; - Z_STRVAL_P( gpc_element ) = estrndup(pValue, valLen); - Z_TYPE_P( gpc_element ) = IS_STRING; - #if PHP_MAJOR_VERSION > 4 - zend_symtable_update( symtable1, pKey1, keyLen + 1, &gpc_element, sizeof( zval *), (void **) &gpc_element_p ); - #else - zend_hash_update( symtable1, pKey1, keyLen + 1, &gpc_element, sizeof( zval *), (void **) &gpc_element_p ); - #endif return 1; } - */ -#else - -static int add_variable( const char * pKey, int keyLen, const char * pValue, int valLen, - void * arg ) -{ - zval * gpc_element, **gpc_element_p; - HashTable * symtable1 = Z_ARRVAL_P((zval * )arg); - register char * pKey1 = (char *)pKey; - - MAKE_STD_ZVAL(gpc_element); - Z_STRLEN_P( gpc_element ) = valLen; - Z_STRVAL_P( gpc_element ) = estrndup(pValue, valLen); - Z_TYPE_P( gpc_element ) = IS_STRING; - zend_hash_update( symtable1, pKey1, keyLen + 1, &gpc_element, sizeof( zval *), (void **) &gpc_element_p ); - return 1; -} -#endif - - -#if defined(ZTS) && PHP_MAJOR_VERSION < 7 -struct param_zts -{ - void *arg; - TSRMLS_D ; -}; - -static int add_variable_zts(const char * pKey, int keyLen, const char * pValue, int valLen, - void * arg ) -{ - struct param_zts * params = (struct param_zts *)arg; - return add_variable(pKey, keyLen, pValue, valLen, params->arg, params->TSRMLS_C); -} -#endif - -static void litespeed_php_import_environment_variables(zval *array_ptr TSRMLS_DC) +static void litespeed_php_import_environment_variables(zval *array_ptr) { char buf[128]; char **env, *p, *t = buf; size_t alloc_size = sizeof(buf); unsigned long nlen; /* ptrdiff_t is not portable */ --#if PHP_MAJOR_VERSION >= 7 if (Z_TYPE(PG(http_globals)[TRACK_VARS_ENV]) == IS_ARRAY && Z_ARR_P(array_ptr) != Z_ARR(PG(http_globals)[TRACK_VARS_ENV]) && zend_hash_num_elements(Z_ARRVAL(PG(http_globals)[TRACK_VARS_ENV])) > 0 @@@ -260,29 -300,29 +254,6 @@@ ZVAL_DUP(array_ptr, &PG(http_globals)[TRACK_VARS_SERVER]); return; } --#else -- if (PG(http_globals)[TRACK_VARS_ENV] && -- array_ptr != PG(http_globals)[TRACK_VARS_ENV] && -- Z_TYPE_P(PG(http_globals)[TRACK_VARS_ENV]) == IS_ARRAY && -- zend_hash_num_elements(Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_ENV])) > 0 -- ) { -- zval_dtor(array_ptr); -- *array_ptr = *PG(http_globals)[TRACK_VARS_ENV]; -- INIT_PZVAL(array_ptr); -- zval_copy_ctor(array_ptr); -- return; -- } else if (PG(http_globals)[TRACK_VARS_SERVER] && -- array_ptr != PG(http_globals)[TRACK_VARS_SERVER] && -- Z_TYPE_P(PG(http_globals)[TRACK_VARS_SERVER]) == IS_ARRAY && -- zend_hash_num_elements(Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_SERVER])) > 0 -- ) { -- zval_dtor(array_ptr); -- *array_ptr = *PG(http_globals)[TRACK_VARS_SERVER]; -- INIT_PZVAL(array_ptr); -- zval_copy_ctor(array_ptr); -- return; -- } --#endif for (env = environ; env != NULL && *env != NULL; env++) { p = strchr(*env, '='); @@@ -556,14 -673,21 +547,20 @@@ static int lsapi_execute_script( zend_f } -static int lsapi_activate_user_ini(TSRMLS_D); ++static int lsapi_activate_user_ini(); -static int lsapi_module_main(int show_source TSRMLS_DC) +static int lsapi_module_main(int show_source) { zend_file_handle file_handle = {0}; - if (php_request_startup(TSRMLS_C) == FAILURE ) { + if (php_request_startup() == FAILURE ) { return -1; } + -#if PHP_MAJOR_VERSION > 5 || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 3) - if (parse_user_ini && lsapi_activate_user_ini(TSRMLS_C) == FAILURE) { ++ if (parse_user_ini && lsapi_activate_user_ini() == FAILURE) { + return -1; + } -#endif ++ if (show_source) { zend_syntax_highlighter_ini syntax_highlighter_ini; @@@ -584,7 -708,7 +581,7 @@@ static int alter_ini( const char * pKey void * arg ) { #if PHP_MAJOR_VERSION >= 7 - zend_string * psKey; - zend_string * psKey; ++ zend_string * psKey; #endif int type = ZEND_INI_PERDIR; if ( '\001' == *pKey ) { @@@ -600,24 -724,368 +597,306 @@@ engine = 0; } else - { + { #if PHP_MAJOR_VERSION >= 7 --keyLen; - psKey = zend_string_init( pKey, keyLen, 1 ); - zend_alter_ini_entry_chars(psKey, + psKey = zend_string_init(pKey, keyLen, 1); + zend_alter_ini_entry_chars(psKey, (char *)pValue, valLen, type, PHP_INI_STAGE_ACTIVATE); - zend_string_release( psKey ); + zend_string_release(psKey); #else zend_alter_ini_entry((char *)pKey, keyLen, (char *)pValue, valLen, - type, PHP_INI_STAGE_ACTIVATE); + type, PHP_INI_STAGE_ACTIVATE); #endif - } + } } return 1; } -static void user_config_cache_entry_dtor( -#if PHP_MAJOR_VERSION >= 7 - zval -#else - void -#endif - *el) ++static void user_config_cache_entry_dtor(zval *el) + { - user_config_cache_entry *entry = -#if PHP_MAJOR_VERSION >= 7 - (user_config_cache_entry *)Z_PTR_P(el) -#else - *(user_config_cache_entry **)el -#endif - ; ++ user_config_cache_entry *entry = (user_config_cache_entry *)Z_PTR_P(el); + zend_hash_destroy(&entry->user_config); + free(entry); + } + + static void user_config_cache_init() + { + zend_hash_init(&user_config_cache, 0, NULL, user_config_cache_entry_dtor, 1); + } + + static int pathlen_without_trailing_slash(char *path) + { + int len = (int)strlen(path); + while (len > 1 && /* mind "/" as root dir */ + path[len-1] == DEFAULT_SLASH) + { + --len; + } + return len; + } + + static inline char* skip_slash(char *s) + { + while (*s == DEFAULT_SLASH) { + ++s; + } + return s; + } + + /** + * Walk down the path_stop starting at path_start. + * + * If path_start = "/path1" and path_stop = "/path1/path2/path3" + * the callback will be called 3 times with the next args: + * + * 1. "/path1/path2/path3" + * ^ end + * ^ start + * 2. "/path1/path2/path3" + * ^ end + * ^ start + * 3. "/path1/path2/path3" + * ^ end + * ^ start + * + * path_stop has to be a subdir of path_start + * or to be path_start itself. + * + * Both path args have to be absolute. + * Trailing slashes are allowed. + * NULL or empty string args are not allowed. + */ + static void walk_down_the_path(char* path_start, + char* path_stop, + void (*cb)(char* begin, + char* end, + void* data), + void* data) + { + char *pos = path_stop + pathlen_without_trailing_slash(path_start); + cb(path_stop, pos, data); + + while ((pos = skip_slash(pos))[0]) { + pos = strchr(pos, DEFAULT_SLASH); + if (!pos) { + /* The last token without trailing slash + */ + cb(path_stop, path_stop + strlen(path_stop), data); + return; + } + cb(path_stop, pos, data); + } + } + -#if PHP_MAJOR_VERSION > 5 || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 3) + + typedef struct { + char *path; + uint path_len; + char *doc_root; + user_config_cache_entry *entry; -#if defined(ZTS) && PHP_MAJOR_VERSION < 7 - TSRMLS_D ; -#endif + } _lsapi_activate_user_ini_ctx; + + typedef int (*fn_activate_user_ini_chain_t) + (_lsapi_activate_user_ini_ctx *ctx, void* next); + + static int lsapi_activate_user_ini_basic_checks(_lsapi_activate_user_ini_ctx *ctx, + void* next) + { + int rc = SUCCESS; + fn_activate_user_ini_chain_t *fn_next = next; + + if (!PG(user_ini_filename) || !*PG(user_ini_filename)) { + return SUCCESS; + } + + /* PATH_TRANSLATED should be defined at this stage */ + ctx->path = SG(request_info).path_translated; + if (!ctx->path || !*ctx->path) { + return FAILURE; + } + - ctx->doc_root = sapi_lsapi_getenv("DOCUMENT_ROOT", 0 -#if defined(ZTS) && PHP_MAJOR_VERSION < 7 - , ctx->TSRMLS_C -#endif - ); ++ ctx->doc_root = sapi_lsapi_getenv("DOCUMENT_ROOT", 0); + DEBUG_MESSAGE("doc_root: %s", ctx->doc_root); + + if (*fn_next) { + rc = (*fn_next)(ctx, fn_next + 1); + } + + return rc; + } + + static int lsapi_activate_user_ini_mk_path(_lsapi_activate_user_ini_ctx *ctx, + void* next) + { + char *path; + int rc = SUCCESS; + fn_activate_user_ini_chain_t *fn_next = next; + + /* Extract dir name from path_translated * and store it in 'path' */ + ctx->path_len = strlen(ctx->path); + path = ctx->path = estrndup(SG(request_info).path_translated, ctx->path_len); + if (!path) + return FAILURE; + ctx->path_len = zend_dirname(path, ctx->path_len); + DEBUG_MESSAGE("dirname: %s", ctx->path); + + if (*fn_next) { + rc = (*fn_next)(ctx, fn_next + 1); + } + + efree(path); + return rc; + } + + static int lsapi_activate_user_ini_mk_realpath(_lsapi_activate_user_ini_ctx *ctx, + void* next) + { + char *real_path; + int rc = SUCCESS; + fn_activate_user_ini_chain_t *fn_next = next; + + if (!IS_ABSOLUTE_PATH(ctx->path, ctx->path_len)) { - real_path = tsrm_realpath(ctx->path, NULL -#if defined(ZTS) && PHP_MAJOR_VERSION < 7 - , ctx->TSRMLS_C -#endif - ); ++ real_path = tsrm_realpath(ctx->path, NULL); + if (!real_path) { + return SUCCESS; + } + ctx->path = real_path; + ctx->path_len = strlen(ctx->path); + DEBUG_MESSAGE("calculated tsrm realpath: %s", real_path); + } else { + DEBUG_MESSAGE("%s is an absolute path", ctx->path); + real_path = NULL; + } + + if (*fn_next) { + rc = (*fn_next)(ctx, fn_next + 1); + } + + if (real_path) + efree(real_path); + return rc; + } + + static int lsapi_activate_user_ini_mk_user_config(_lsapi_activate_user_ini_ctx *ctx, + void* next) + { + fn_activate_user_ini_chain_t *fn_next = next; + + /* Find cached config entry: If not found, create one */ -#if PHP_MAJOR_VERSION >= 7 + ctx->entry = zend_hash_str_find_ptr(&user_config_cache, ctx->path, ctx->path_len); -#else - { - user_config_cache_entry **entry_pp; - if (SUCCESS == zend_hash_find(&user_config_cache, ctx->path, - ctx->path_len + 1, (void **) &entry_pp)) - ctx->entry = *entry_pp; - else - ctx->entry = NULL; - } -#endif + + if (ctx->entry) { + DEBUG_MESSAGE("found entry for %s", ctx->path); + } else { + DEBUG_MESSAGE("entry for %s not found, creating new entry", ctx->path); + ctx->entry = pemalloc(sizeof(user_config_cache_entry), 1); + ctx->entry->expires = 0; + zend_hash_init(&ctx->entry->user_config, 0, NULL, -#if PHP_MAJOR_VERSION <= 5 - (dtor_func_t) -#endif + config_zval_dtor, 1); -#if PHP_MAJOR_VERSION >= 7 + zend_hash_str_update_ptr(&user_config_cache, ctx->path, + ctx->path_len, ctx->entry); -#else - zend_hash_update(&user_config_cache, ctx->path, ctx->path_len + 1, - &ctx->entry, sizeof(&ctx->entry), NULL); -#endif + } + + if (*fn_next) { + return (*fn_next)(ctx, fn_next + 1); + } else { + return SUCCESS; + } + } + + static void walk_down_the_path_callback(char* begin, + char* end, + void* data) + { + _lsapi_activate_user_ini_ctx *ctx = data; + char tmp = end[0]; + end[0] = 0; + DEBUG_MESSAGE("parsing %s%c%s", begin, DEFAULT_SLASH, PG(user_ini_filename)); - php_parse_user_ini_file(begin, PG(user_ini_filename), &ctx->entry->user_config -#if defined(ZTS) && PHP_MAJOR_VERSION < 7 - , ctx->TSRMLS_C -#endif - ); ++ php_parse_user_ini_file(begin, PG(user_ini_filename), &ctx->entry->user_config); + end[0] = tmp; + } + + static int lsapi_activate_user_ini_walk_down_the_path(_lsapi_activate_user_ini_ctx *ctx, + void* next) + { - time_t request_time = sapi_get_request_time( -#if defined(ZTS) && PHP_MAJOR_VERSION < 7 - ctx->TSRMLS_C -#endif - ); ++ time_t request_time = sapi_get_request_time(); + uint path_len, docroot_len; + int rc = SUCCESS; + fn_activate_user_ini_chain_t *fn_next = next; + + if (!ctx->entry->expires || request_time > ctx->entry->expires) + { + docroot_len = ctx->doc_root && ctx->doc_root[0] + ? pathlen_without_trailing_slash(ctx->doc_root) + : 0; + + int is_outside_of_docroot = !docroot_len || + ctx->path_len < docroot_len || + strncmp(ctx->path, ctx->doc_root, docroot_len) != 0; + + if (is_outside_of_docroot) { - php_parse_user_ini_file(ctx->path, PG(user_ini_filename), &ctx->entry->user_config -#if defined(ZTS) && PHP_MAJOR_VERSION < 7 - , ctx->TSRMLS_C -#endif - ); ++ php_parse_user_ini_file(ctx->path, PG(user_ini_filename), ++ &ctx->entry->user_config); + } else { + walk_down_the_path(ctx->doc_root, ctx->path, + &walk_down_the_path_callback, ctx); + } + + ctx->entry->expires = request_time + PG(user_ini_cache_ttl); + } + + if (*fn_next) { + rc = (*fn_next)(ctx, fn_next + 1); + } + + return rc; + } + + static int lsapi_activate_user_ini_finally(_lsapi_activate_user_ini_ctx *ctx, + void* next) + { + int rc = SUCCESS; + fn_activate_user_ini_chain_t *fn_next = next; + + DEBUG_MESSAGE("calling php_ini_activate_config()"); - php_ini_activate_config(&ctx->entry->user_config, PHP_INI_PERDIR, PHP_INI_STAGE_HTACCESS -#if defined(ZTS) && PHP_MAJOR_VERSION < 7 - , ctx->TSRMLS_C -#endif - ); ++ php_ini_activate_config(&ctx->entry->user_config, PHP_INI_PERDIR, ++ PHP_INI_STAGE_HTACCESS); + + if (*fn_next) { + rc = (*fn_next)(ctx, fn_next + 1); + } + + return rc; + } + + static int lsapi_activate_user_ini(TSRMLS_D) + { + _lsapi_activate_user_ini_ctx ctx; + /** + * The reason to have this function list stacked + * is each function now can define a scoped destructor. + * + * Passing control via function pointer is a sign of low coupling, + * which means dependencies between these functions are to be + * controlled from a single place + * (here below, by modifying this function list order) + */ + static const fn_activate_user_ini_chain_t fn_chain[] = { + &lsapi_activate_user_ini_basic_checks, + &lsapi_activate_user_ini_mk_path, + &lsapi_activate_user_ini_mk_realpath, + &lsapi_activate_user_ini_mk_user_config, + &lsapi_activate_user_ini_walk_down_the_path, + &lsapi_activate_user_ini_finally, + NULL + }; + -#if defined(ZTS) && PHP_MAJOR_VERSION < 7 - ctx.TSRMLS_C = TSRMLS_C; -#endif - + return fn_chain[0](&ctx, (fn_activate_user_ini_chain_t*)(fn_chain + 1)); + } + -#endif static void override_ini() { @@@ -809,16 -1277,16 +1088,16 @@@ static int cli_main( int argc, char * a } break; case 'v': - if (php_request_startup(TSRMLS_C) != FAILURE) { + if (php_request_startup() != FAILURE) { #if ZEND_DEBUG - php_printf("PHP %s (%s) (built: %s %s) (DEBUG)\nCopyright (c) 1997-2016 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version()); + php_printf("PHP %s (%s) (built: %s %s) (DEBUG)\nCopyright (c) 1997-2015 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version()); #else - php_printf("PHP %s (%s) (built: %s %s)\nCopyright (c) 1997-2016 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version()); + php_printf("PHP %s (%s) (built: %s %s)\nCopyright (c) 1997-2015 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version()); #endif #ifdef PHP_OUTPUT_NEWAPI - php_output_end_all(TSRMLS_C); + php_output_end_all(); #else - php_end_ob_buffers(1 TSRMLS_CC); + php_end_ob_buffers(1); #endif php_request_shutdown( NULL ); ret = 0;