Commit:    6c2a8068207a02b3d7ae7416a9967dad0a81e61f
Author:    Dmitry Stogov <dmi...@zend.com>         Fri, 29 Nov 2013 00:57:49 
+0400
Parents:   5d2576264653c2faaca9cd7d64218d10ab612408
Branches:  PHP-5.6 master

Link:       
http://git.php.net/?p=php-src.git;a=commitdiff;h=6c2a8068207a02b3d7ae7416a9967dad0a81e61f

Log:
Avoid interned hash key duplication and hash key length recaclulation

Changed paths:
  M  Zend/zend_builtin_functions.c
  M  Zend/zend_hash.c
  M  ext/pcre/php_pcre.c
  M  ext/soap/php_http.c


Diff:
diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c
index d779e8a..91bca37 100644
--- a/Zend/zend_builtin_functions.c
+++ b/Zend/zend_builtin_functions.c
@@ -609,9 +609,9 @@ ZEND_FUNCTION(each)
        Z_ADDREF_P(entry);
 
        /* add the key elements */
-       switch (zend_hash_get_current_key_ex(target_hash, &string_key, 
&string_key_len, &num_key, 1, NULL)) {
+       switch (zend_hash_get_current_key_ex(target_hash, &string_key, 
&string_key_len, &num_key, 0, NULL)) {
                case HASH_KEY_IS_STRING:
-                       add_get_index_stringl(return_value, 0, string_key, 
string_key_len-1, (void **) &inserted_pointer, 0);
+                       add_get_index_stringl(return_value, 0, string_key, 
string_key_len-1, (void **) &inserted_pointer, !IS_INTERNED(string_key));
                        break;
                case HASH_KEY_IS_LONG:
                        add_get_index_long(return_value, 0, num_key, (void **) 
&inserted_pointer);
@@ -950,7 +950,7 @@ static void add_class_vars(zend_class_entry *ce, int 
statics, zval *return_value
                        zval_update_constant(&prop_copy, 0 TSRMLS_CC);
                }
 
-               add_assoc_zval(return_value, key, prop_copy);
+               zend_hash_update(Z_ARRVAL_P(return_value), key, key_len, 
&prop_copy, sizeof(zval*), NULL);
        }
 }
 /* }}} */
@@ -1020,7 +1020,14 @@ ZEND_FUNCTION(get_object_vars)
                                zend_unmangle_property_name_ex(key, key_len - 
1, &class_name, &prop_name, (int*) &prop_len);
                                /* Not separating references */
                                Z_ADDREF_PP(value);
-                               add_assoc_zval_ex(return_value, prop_name, 
prop_len + 1, *value);
+                               if (IS_INTERNED(key) && prop_name != key) {
+                                       /* we can't use substring of interned 
string as a new key */
+                                       char *tmp = estrndup(prop_name, 
prop_len);
+                                       add_assoc_zval_ex(return_value, tmp, 
prop_len + 1, *value);
+                                       efree(tmp);
+                               } else {
+                                       add_assoc_zval_ex(return_value, 
prop_name, prop_len + 1, *value);
+                               }
                        }
                }
                zend_hash_move_forward_ex(properties, &pos);
@@ -1476,6 +1483,7 @@ ZEND_FUNCTION(crash)
 ZEND_FUNCTION(get_included_files)
 {
        char *entry;
+       uint entry_len;
 
        if (zend_parse_parameters_none() == FAILURE) {
                return;
@@ -1483,8 +1491,8 @@ ZEND_FUNCTION(get_included_files)
 
        array_init(return_value);
        zend_hash_internal_pointer_reset(&EG(included_files));
-       while (zend_hash_get_current_key(&EG(included_files), &entry, NULL, 1) 
== HASH_KEY_IS_STRING) {
-               add_next_index_string(return_value, entry, 0);
+       while (zend_hash_get_current_key_ex(&EG(included_files), &entry, 
&entry_len, NULL, 0, NULL) == HASH_KEY_IS_STRING) {
+               add_next_index_stringl(return_value, entry, entry_len-1, 
!IS_INTERNED(entry));
                zend_hash_move_forward(&EG(included_files));
        }
 }
diff --git a/Zend/zend_hash.c b/Zend/zend_hash.c
index b8aa679..e938d1d 100644
--- a/Zend/zend_hash.c
+++ b/Zend/zend_hash.c
@@ -1123,7 +1123,7 @@ ZEND_API void zend_hash_get_current_key_zval_ex(const 
HashTable *ht, zval *key,
                Z_TYPE_P(key) = IS_NULL;
        } else if (p->nKeyLength) {
                Z_TYPE_P(key) = IS_STRING;
-               Z_STRVAL_P(key) = estrndup(p->arKey, p->nKeyLength - 1);
+               Z_STRVAL_P(key) = IS_INTERNED(p->arKey) ? (char*)p->arKey : 
estrndup(p->arKey, p->nKeyLength - 1);
                Z_STRLEN_P(key) = p->nKeyLength - 1;
        } else {
                Z_TYPE_P(key) = IS_LONG;
diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c
index 7d34d9f..1e88291 100644
--- a/ext/pcre/php_pcre.c
+++ b/ext/pcre/php_pcre.c
@@ -1343,6 +1343,7 @@ static void 
preg_replace_impl(INTERNAL_FUNCTION_PARAMETERS, int is_callable_repl
        int                              limit_val = -1;
        long                    limit = -1;
        char                    *string_key;
+       uint                     string_key_len;
        ulong                    num_key;
        char                    *callback_name;
        int                              replace_count=0, old_replace_count;
@@ -1394,10 +1395,10 @@ static void 
preg_replace_impl(INTERNAL_FUNCTION_PARAMETERS, int is_callable_repl
                        if ((result = php_replace_in_subject(*regex, *replace, 
subject_entry, &result_len, limit_val, is_callable_replace, &replace_count 
TSRMLS_CC)) != NULL) {
                                if (!is_filter || replace_count > 
old_replace_count) {
                                        /* Add to return array */
-                                       
switch(zend_hash_get_current_key(Z_ARRVAL_PP(subject), &string_key, &num_key, 
0))
+                                       
switch(zend_hash_get_current_key_ex(Z_ARRVAL_PP(subject), &string_key, 
&string_key_len, &num_key, 0, NULL))
                                        {
                                        case HASH_KEY_IS_STRING:
-                                               add_assoc_stringl(return_value, 
string_key, result, result_len, 0);
+                                               
add_assoc_stringl_ex(return_value, string_key, string_key_len, result, 
result_len, 0);
                                                break;
 
                                        case HASH_KEY_IS_LONG:
@@ -1770,6 +1771,7 @@ PHPAPI void  php_pcre_grep_impl(pcre_cache_entry *pce, 
zval *input, zval *return
        int                              size_offsets;          /* Size of the 
offsets array */
        int                              count = 0;                     /* 
Count of matched subpatterns */
        char                    *string_key;
+       uint                     string_key_len;
        ulong                    num_key;
        zend_bool                invert;                        /* Whether to 
return non-matching
                                                                                
   entries */
@@ -1828,11 +1830,11 @@ PHPAPI void  php_pcre_grep_impl(pcre_cache_entry *pce, 
zval *input, zval *return
                        Z_ADDREF_PP(entry);
 
                        /* Add to return array */
-                       switch (zend_hash_get_current_key(Z_ARRVAL_P(input), 
&string_key, &num_key, 0))
+                       switch (zend_hash_get_current_key_ex(Z_ARRVAL_P(input), 
&string_key, &string_key_len, &num_key, 0, NULL))
                        {
                                case HASH_KEY_IS_STRING:
                                        
zend_hash_update(Z_ARRVAL_P(return_value), string_key,
-                                                                        
strlen(string_key)+1, entry, sizeof(zval *), NULL);
+                                                                        
string_key_len, entry, sizeof(zval *), NULL);
                                        break;
 
                                case HASH_KEY_IS_LONG:
diff --git a/ext/soap/php_http.c b/ext/soap/php_http.c
index 86ab03d..14366f1 100644
--- a/ext/soap/php_http.c
+++ b/ext/soap/php_http.c
@@ -807,6 +807,7 @@ try_again:
                if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_cookies", 
sizeof("_cookies"), (void **)&cookies) == SUCCESS) {
                        zval **data;
                        char *key;
+                       uint key_len;
                        int i, n;
 
                        has_cookies = 1;
@@ -816,7 +817,7 @@ try_again:
                                smart_str_append_const(&soap_headers, "Cookie: 
");
                                for (i = 0; i < n; i++) {
                                        
zend_hash_get_current_data(Z_ARRVAL_PP(cookies), (void **)&data);
-                                       
zend_hash_get_current_key(Z_ARRVAL_PP(cookies), &key, NULL, FALSE);
+                                       
zend_hash_get_current_key_ex(Z_ARRVAL_PP(cookies), &key, &key_len, NULL, 0, 
NULL);
 
                                        if (Z_TYPE_PP(data) == IS_ARRAY) {
                                          zval** value;
@@ -829,7 +830,7 @@ try_again:
                                                      
(zend_hash_index_find(Z_ARRVAL_PP(data), 2, (void**)&tmp) == FAILURE ||
                                                       
in_domain(phpurl->host,Z_STRVAL_PP(tmp))) &&
                                                      (use_ssl || 
zend_hash_index_find(Z_ARRVAL_PP(data), 3, (void**)&tmp) == FAILURE)) {
-                                                               
smart_str_appendl(&soap_headers, key, strlen(key));
+                                                               
smart_str_appendl(&soap_headers, key, key_len);
                                                                
smart_str_appendc(&soap_headers, '=');
                                                                
smart_str_appendl(&soap_headers, Z_STRVAL_PP(value), Z_STRLEN_PP(value));
                                                                
smart_str_appendc(&soap_headers, ';');


--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to