]> granicus.if.org Git - php/commitdiff
Avoid interned hash key duplication and hash key length recaclulation
authorDmitry Stogov <dmitry@zend.com>
Thu, 28 Nov 2013 20:57:49 +0000 (00:57 +0400)
committerDmitry Stogov <dmitry@zend.com>
Thu, 28 Nov 2013 20:57:49 +0000 (00:57 +0400)
Zend/zend_builtin_functions.c
Zend/zend_hash.c
ext/pcre/php_pcre.c
ext/soap/php_http.c

index d779e8a5ee6a3548b475fb26bb8d9c8da54f6e71..91bca37a1b203a9c38a7e253218db95434b5e4c8 100644 (file)
@@ -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));
        }
 }
index b8aa679f965c8d4eaf406aa714d389d349f62227..e938d1d3d7fac924de85b969d4a4a9155361c5ca 100644 (file)
@@ -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;
index 7d34d9feb15a81b5e80973cf1aaa1c4936543173..1e882910d4b46986ab84f9d8449f17c36204772f 100644 (file)
@@ -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:
index 86ab03d9c80c7e1e8196e16e52bc267bddba6f09..14366f12cc4070b8265b789a824a7535de918eb8 100644 (file)
@@ -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, ';');