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