Avoid interned hash key duplication and hash key length recaclulation

This commit is contained in:
Dmitry Stogov 2013-11-29 00:57:49 +04:00
parent 5d25762646
commit 6c2a806820
4 changed files with 24 additions and 13 deletions

View 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));
}
}

View 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;

View 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:

View 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, ';');