jani Mon Oct 1 12:34:19 2007 UTC Modified files: (Branch: PHP_5_3) /php-src/ext/standard array.c php_var.h Log: MFH: sync (adds php_prefix_varname() API function)
http://cvs.php.net/viewvc.cgi/php-src/ext/standard/array.c?r1=1.308.2.21.2.37&r2=1.308.2.21.2.37.2.1&diff_format=u Index: php-src/ext/standard/array.c diff -u php-src/ext/standard/array.c:1.308.2.21.2.37 php-src/ext/standard/array.c:1.308.2.21.2.37.2.1 --- php-src/ext/standard/array.c:1.308.2.21.2.37 Sat Sep 22 15:38:00 2007 +++ php-src/ext/standard/array.c Mon Oct 1 12:34:19 2007 @@ -21,7 +21,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: array.c,v 1.308.2.21.2.37 2007/09/22 15:38:00 iliaa Exp $ */ +/* $Id: array.c,v 1.308.2.21.2.37.2.1 2007/10/01 12:34:19 jani Exp $ */ #include "php.h" #include "php_ini.h" @@ -618,7 +618,7 @@ /* check if comparison function is valid */ #define PHP_ARRAY_CMP_FUNC_CHECK(func_name) \ if (!zend_is_callable(*func_name, 0, NULL)) { \ - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid comparison function."); \ + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid comparison function"); \ BG(user_compare_fci_cache) = old_user_compare_fci_cache; \ BG(user_compare_func_name) = old_compare_func; \ RETURN_FALSE; \ @@ -1317,82 +1317,86 @@ } /* }}} */ +PHPAPI int php_prefix_varname(zval *result, zval *prefix, char *var_name, int var_name_len, zend_bool add_underscore TSRMLS_DC) /* {{{ */ +{ + Z_STRLEN_P(result) = Z_STRLEN_P(prefix) + (add_underscore ? 1 : 0) + var_name_len; + Z_TYPE_P(result) = IS_STRING; + Z_STRVAL_P(result) = emalloc(Z_STRLEN_P(result) + 1); + memcpy(Z_STRVAL_P(result), Z_STRVAL_P(prefix), Z_STRLEN_P(prefix)); + + if (add_underscore) { + Z_STRVAL_P(result)[Z_STRLEN_P(prefix)] = '_'; + } + + memcpy(Z_STRVAL_P(result) + Z_STRLEN_P(prefix) + (add_underscore ? 1 : 0), var_name, var_name_len + 1); + + return SUCCESS; +} +/* }}} */ + /* {{{ proto int extract(array var_array [, int extract_type [, string prefix]]) Imports variables into symbol table from an array */ PHP_FUNCTION(extract) { - zval **var_array, **z_extract_type, **prefix; + zval *var_array, *prefix = NULL; + long extract_type = EXTR_OVERWRITE; zval **entry, *data; char *var_name; - smart_str final_name = {0}; ulong num_key; uint var_name_len; - int var_exists, extract_type, key_type, count = 0; + int var_exists, key_type, count = 0; int extract_refs = 0; HashPosition pos; - switch (ZEND_NUM_ARGS()) { - case 1: - if (zend_get_parameters_ex(1, &var_array) == FAILURE) { - WRONG_PARAM_COUNT; - } - extract_type = EXTR_OVERWRITE; - break; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|lz/", &var_array, &extract_type, &prefix) == FAILURE) { + return; + } - case 2: - if (zend_get_parameters_ex(2, &var_array, &z_extract_type) == FAILURE) { - WRONG_PARAM_COUNT; - } - convert_to_long_ex(z_extract_type); - extract_type = Z_LVAL_PP(z_extract_type); - extract_refs = (extract_type & EXTR_REFS); - extract_type &= 0xff; - if (extract_type > EXTR_SKIP && extract_type <= EXTR_PREFIX_IF_EXISTS) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Prefix expected to be specified"); - return; - } - break; - - case 3: - if (zend_get_parameters_ex(3, &var_array, &z_extract_type, &prefix) == FAILURE) { - WRONG_PARAM_COUNT; - } - convert_to_long_ex(z_extract_type); - extract_type = Z_LVAL_PP(z_extract_type); - extract_refs = (extract_type & EXTR_REFS); - extract_type &= 0xff; - convert_to_string_ex(prefix); - break; + extract_refs = (extract_type & EXTR_REFS); + extract_type &= 0xff; - default: - WRONG_PARAM_COUNT; - break; - } - if (extract_type < EXTR_OVERWRITE || extract_type > EXTR_IF_EXISTS) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown extract type"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid extract type"); return; } - - if (Z_TYPE_PP(var_array) != IS_ARRAY) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "First argument should be an array"); + + if (extract_type > EXTR_SKIP && extract_type <= EXTR_PREFIX_IF_EXISTS && ZEND_NUM_ARGS() < 3) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "specified extract type requires the prefix parameter"); return; } - - zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(var_array), &pos); - while (zend_hash_get_current_data_ex(Z_ARRVAL_PP(var_array), (void **)&entry, &pos) == SUCCESS) { - key_type = zend_hash_get_current_key_ex(Z_ARRVAL_PP(var_array), &var_name, &var_name_len, &num_key, 0, &pos); + + if (prefix) { + convert_to_string(prefix); + if (Z_STRLEN_P(prefix) && !php_valid_var_name(Z_STRVAL_P(prefix), Z_STRLEN_P(prefix))) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "prefix is not a valid identifier"); + return; + } + } + + zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(var_array), &pos); + while (zend_hash_get_current_data_ex(Z_ARRVAL_P(var_array), (void **)&entry, &pos) == SUCCESS) { + zval final_name; + + ZVAL_NULL(&final_name); + + key_type = zend_hash_get_current_key_ex(Z_ARRVAL_P(var_array), &var_name, &var_name_len, &num_key, 0, &pos); var_exists = 0; if (key_type == HASH_KEY_IS_STRING) { var_name_len--; var_exists = zend_hash_exists(EG(active_symbol_table), var_name, var_name_len + 1); - } else if (extract_type == EXTR_PREFIX_ALL || extract_type == EXTR_PREFIX_INVALID) { - smart_str_appendl(&final_name, Z_STRVAL_PP(prefix), Z_STRLEN_PP(prefix)); - smart_str_appendc(&final_name, '_'); - smart_str_append_long(&final_name, num_key); + } else if (key_type == HASH_KEY_IS_LONG && + (extract_type == EXTR_PREFIX_ALL || + extract_type == EXTR_PREFIX_INVALID) + ) { + zval num; + + ZVAL_LONG(&num, num_key); + convert_to_string(&num); + php_prefix_varname(&final_name, prefix, Z_STRVAL(num), Z_STRLEN(num), 1 TSRMLS_CC); + zval_dtor(&num); } else { - zend_hash_move_forward_ex(Z_ARRVAL_PP(var_array), &pos); + zend_hash_move_forward_ex(Z_ARRVAL_P(var_array), &pos); continue; } @@ -1403,90 +1407,84 @@ case EXTR_OVERWRITE: /* GLOBALS protection */ - if (var_exists && !strcmp(var_name, "GLOBALS")) { + if (var_exists && + var_name_len == sizeof("GLOBALS") && + !strcmp(var_name, "GLOBALS") + ) { break; } - smart_str_appendl(&final_name, var_name, var_name_len); + ZVAL_STRINGL(&final_name, var_name, var_name_len, 1); break; case EXTR_PREFIX_IF_EXISTS: if (var_exists) { - smart_str_appendl(&final_name, Z_STRVAL_PP(prefix), Z_STRLEN_PP(prefix)); - smart_str_appendc(&final_name, '_'); - smart_str_appendl(&final_name, var_name, var_name_len); + php_prefix_varname(&final_name, prefix, var_name, var_name_len, 1 TSRMLS_CC); } break; case EXTR_PREFIX_SAME: - if (!var_exists) - smart_str_appendl(&final_name, var_name, var_name_len); + if (!var_exists && var_name_len != 0) { + ZVAL_STRINGL(&final_name, var_name, var_name_len, 1); + } /* break omitted intentionally */ case EXTR_PREFIX_ALL: - if (final_name.len == 0 && var_name_len != 0) { - smart_str_appendl(&final_name, Z_STRVAL_PP(prefix), Z_STRLEN_PP(prefix)); - smart_str_appendc(&final_name, '_'); - smart_str_appendl(&final_name, var_name, var_name_len); + if (Z_TYPE(final_name) == IS_NULL && var_name_len != 0) { + php_prefix_varname(&final_name, prefix, var_name, var_name_len, 1 TSRMLS_CC); } break; case EXTR_PREFIX_INVALID: - if (final_name.len == 0) { + if (Z_TYPE(final_name) == IS_NULL) { if (!php_valid_var_name(var_name, var_name_len)) { - smart_str_appendl(&final_name, Z_STRVAL_PP(prefix), Z_STRLEN_PP(prefix)); - smart_str_appendc(&final_name, '_'); - smart_str_appendl(&final_name, var_name, var_name_len); - } else - smart_str_appendl(&final_name, var_name, var_name_len); + php_prefix_varname(&final_name, prefix, var_name, var_name_len, 1 TSRMLS_CC); + } else { + ZVAL_STRINGL(&final_name, var_name, var_name_len, 1); + } } break; default: - if (!var_exists) - smart_str_appendl(&final_name, var_name, var_name_len); + if (!var_exists) { + ZVAL_STRINGL(&final_name, var_name, var_name_len, 1); + } break; } - if (final_name.len) { - smart_str_0(&final_name); - if (php_valid_var_name(final_name.c, final_name.len)) { - if (extract_refs) { - zval **orig_var; - - if (zend_hash_find(EG(active_symbol_table), final_name.c, final_name.len+1, (void **) &orig_var) == SUCCESS) { - SEPARATE_ZVAL_TO_MAKE_IS_REF(entry); - zval_add_ref(entry); + if (Z_TYPE(final_name) != IS_NULL && php_valid_var_name(Z_STRVAL(final_name), Z_STRLEN(final_name))) { + if (extract_refs) { + zval **orig_var; + + if (zend_hash_find(EG(active_symbol_table), Z_STRVAL(final_name), Z_STRLEN(final_name) + 1, (void **) &orig_var) == SUCCESS) { + SEPARATE_ZVAL_TO_MAKE_IS_REF(entry); + zval_add_ref(entry); - zval_ptr_dtor(orig_var); + zval_ptr_dtor(orig_var); - *orig_var = *entry; + *orig_var = *entry; + } else { + if (var_array->refcount > 1 || *entry == EG(uninitialized_zval_ptr)) { + SEPARATE_ZVAL_TO_MAKE_IS_REF(entry); } else { - if ((*var_array)->refcount > 1 || *entry == EG(uninitialized_zval_ptr)) { - SEPARATE_ZVAL_TO_MAKE_IS_REF(entry); - } else { - (*entry)->is_ref = 1; - } - zval_add_ref(entry); - zend_hash_update(EG(active_symbol_table), final_name.c, final_name.len+1, (void **) entry, sizeof(zval *), NULL); + (*entry)->is_ref = 1; } - } else { - MAKE_STD_ZVAL(data); - *data = **entry; - zval_copy_ctor(data); - - ZEND_SET_SYMBOL_WITH_LENGTH(EG(active_symbol_table), final_name.c, final_name.len+1, data, 1, 0); + zval_add_ref(entry); + zend_hash_update(EG(active_symbol_table), Z_STRVAL(final_name), Z_STRLEN(final_name) + 1, (void **) entry, sizeof(zval *), NULL); } + } else { + MAKE_STD_ZVAL(data); + *data = **entry; + zval_copy_ctor(data); - count++; + ZEND_SET_SYMBOL_WITH_LENGTH(EG(active_symbol_table), Z_STRVAL(final_name), Z_STRLEN(final_name) + 1, data, 1, 0); } - final_name.len = 0; + count++; } + zval_dtor(&final_name); - zend_hash_move_forward_ex(Z_ARRVAL_PP(var_array), &pos); + zend_hash_move_forward_ex(Z_ARRVAL_P(var_array), &pos); } - smart_str_free(&final_name); - RETURN_LONG(count); } /* }}} */ @@ -3157,7 +3155,7 @@ BG(user_compare_func_name) = args[arr_argc + 1];/* data - key */ } else { efree(args); - php_error_docref(NULL TSRMLS_CC, E_WARNING, "data_compare_type is %d. key_compare_type is %d. This should never happen. Please report as a bug.", data_compare_type, key_compare_type); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "data_compare_type is %d. key_compare_type is %d. This should never happen. Please report as a bug", data_compare_type, key_compare_type); return; } } else { http://cvs.php.net/viewvc.cgi/php-src/ext/standard/php_var.h?r1=1.30.2.1.2.6&r2=1.30.2.1.2.6.2.1&diff_format=u Index: php-src/ext/standard/php_var.h diff -u php-src/ext/standard/php_var.h:1.30.2.1.2.6 php-src/ext/standard/php_var.h:1.30.2.1.2.6.2.1 --- php-src/ext/standard/php_var.h:1.30.2.1.2.6 Tue May 22 14:34:22 2007 +++ php-src/ext/standard/php_var.h Mon Oct 1 12:34:19 2007 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_var.h,v 1.30.2.1.2.6 2007/05/22 14:34:22 tony2001 Exp $ */ +/* $Id: php_var.h,v 1.30.2.1.2.6.2.1 2007/10/01 12:34:19 jani Exp $ */ #ifndef PHP_VAR_H #define PHP_VAR_H @@ -69,21 +69,21 @@ static inline int php_varname_check(char *name, int name_len, zend_bool silent TSRMLS_DC) /* {{{ */ { - if (name_len == sizeof("GLOBALS") && !memcmp(name, "GLOBALS", sizeof("GLOBALS"))) { + if (name_len == sizeof("GLOBALS") - 1 && !memcmp(name, "GLOBALS", sizeof("GLOBALS") - 1)) { if (!silent) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Attempted GLOBALS variable overwrite"); } return FAILURE; } else if (name[0] == '_' && ( - (name_len == sizeof("_GET") && !memcmp(name, "_GET", sizeof("_GET"))) || - (name_len == sizeof("_POST") && !memcmp(name, "_POST", sizeof("_POST"))) || - (name_len == sizeof("_COOKIE") && !memcmp(name, "_COOKIE", sizeof("_COOKIE"))) || - (name_len == sizeof("_ENV") && !memcmp(name, "_ENV", sizeof("_ENV"))) || - (name_len == sizeof("_SERVER") && !memcmp(name, "_SERVER", sizeof("_SERVER"))) || - (name_len == sizeof("_SESSION") && !memcmp(name, "_SESSION", sizeof("_SESSION"))) || - (name_len == sizeof("_FILES") && !memcmp(name, "_FILES", sizeof("_FILES"))) || - (name_len == sizeof("_REQUEST") && !memcmp(name, "_REQUEST", sizeof("_REQUEST"))) + (name_len == sizeof("_GET") - 1 && !memcmp(name, "_GET", sizeof("_GET") - 1)) || + (name_len == sizeof("_POST") - 1 && !memcmp(name, "_POST", sizeof("_POST") - 1)) || + (name_len == sizeof("_COOKIE") - 1 && !memcmp(name, "_COOKIE", sizeof("_COOKIE") - 1)) || + (name_len == sizeof("_ENV") - 1 && !memcmp(name, "_ENV", sizeof("_ENV") - 1)) || + (name_len == sizeof("_SERVER") - 1 && !memcmp(name, "_SERVER", sizeof("_SERVER") - 1)) || + (name_len == sizeof("_SESSION") - 1 && !memcmp(name, "_SESSION", sizeof("_SESSION") - 1)) || + (name_len == sizeof("_FILES") - 1 && !memcmp(name, "_FILES", sizeof("_FILES") - 1)) || + (name_len == sizeof("_REQUEST") -1 && !memcmp(name, "_REQUEST", sizeof("_REQUEST") - 1)) ) ) { if (!silent) { @@ -92,14 +92,14 @@ return FAILURE; } else if (name[0] == 'H' && ( - (name_len == sizeof("HTTP_POST_VARS") && !memcmp(name, "HTTP_POST_VARS", sizeof("HTTP_POST_VARS"))) || - (name_len == sizeof("HTTP_GET_VARS") && !memcmp(name, "HTTP_GET_VARS", sizeof("HTTP_GET_VARS"))) || - (name_len == sizeof("HTTP_COOKIE_VARS") && !memcmp(name, "HTTP_COOKIE_VARS", sizeof("HTTP_COOKIE_VARS"))) || - (name_len == sizeof("HTTP_ENV_VARS") && !memcmp(name, "HTTP_ENV_VARS", sizeof("HTTP_ENV_VARS"))) || - (name_len == sizeof("HTTP_SERVER_VARS") && !memcmp(name, "HTTP_SERVER_VARS", sizeof("HTTP_SERVER_VARS"))) || - (name_len == sizeof("HTTP_SESSION_VARS") && !memcmp(name, "HTTP_SESSION_VARS", sizeof("HTTP_SESSION_VARS"))) || - (name_len == sizeof("HTTP_RAW_POST_DATA") && !memcmp(name, "HTTP_RAW_POST_DATA", sizeof("HTTP_RAW_POST_DATA"))) || - (name_len == sizeof("HTTP_POST_FILES") && !memcmp(name, "HTTP_POST_FILES", sizeof("HTTP_POST_FILES"))) + (name_len == sizeof("HTTP_POST_VARS") - 1 && !memcmp(name, "HTTP_POST_VARS", sizeof("HTTP_POST_VARS") - 1)) || + (name_len == sizeof("HTTP_GET_VARS") - 1 && !memcmp(name, "HTTP_GET_VARS", sizeof("HTTP_GET_VARS") - 1)) || + (name_len == sizeof("HTTP_COOKIE_VARS") - 1 && !memcmp(name, "HTTP_COOKIE_VARS", sizeof("HTTP_COOKIE_VARS") - 1)) || + (name_len == sizeof("HTTP_ENV_VARS") - 1 && !memcmp(name, "HTTP_ENV_VARS", sizeof("HTTP_ENV_VARS") - 1)) || + (name_len == sizeof("HTTP_SERVER_VARS") - 1 && !memcmp(name, "HTTP_SERVER_VARS", sizeof("HTTP_SERVER_VARS") - 1)) || + (name_len == sizeof("HTTP_SESSION_VARS") - 1 && !memcmp(name, "HTTP_SESSION_VARS", sizeof("HTTP_SESSION_VARS") - 1)) || + (name_len == sizeof("HTTP_RAW_POST_DATA") - 1 && !memcmp(name, "HTTP_RAW_POST_DATA", sizeof("HTTP_RAW_POST_DATA") - 1)) || + (name_len == sizeof("HTTP_POST_FILES") - 1 && !memcmp(name, "HTTP_POST_FILES", sizeof("HTTP_POST_FILES") - 1)) ) ) { if (!silent) {
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php