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

Reply via email to