summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2018-06-09 13:15:37 +0200
committerNikita Popov <nikita.ppv@gmail.com>2018-06-09 13:20:13 +0200
commit777187cbafb8c1844971169dc97d38a633094aaf (patch)
tree9fd751d73f841f551f604c47367793af17c92456
parent9cd2d77514aa71359eac0ea080901e7c021681c9 (diff)
downloadphp-git-777187cbafb8c1844971169dc97d38a633094aaf.tar.gz
Don't use UNREFs during array operations
Perform DEREFs instead. We were already doing this in some, but not all places. While UNREFs are supposed to be transparent, in practice they have rare observable side effects. Calling array_merge() on an array should never change how that array behaves.
-rw-r--r--ext/standard/array.c16
1 files changed, 8 insertions, 8 deletions
diff --git a/ext/standard/array.c b/ext/standard/array.c
index 482f68fee4..eb89c7061b 100644
--- a/ext/standard/array.c
+++ b/ext/standard/array.c
@@ -3612,7 +3612,7 @@ PHP_FUNCTION(array_slice)
}
if (UNEXPECTED(Z_ISREF_P(entry)) &&
UNEXPECTED(Z_REFCOUNT_P(entry) == 1)) {
- ZVAL_UNREF(entry);
+ entry = Z_REFVAL_P(entry);
}
Z_TRY_ADDREF_P(entry);
ZEND_HASH_FILL_ADD(entry);
@@ -3725,7 +3725,7 @@ PHPAPI int php_array_merge(HashTable *dest, HashTable *src) /* {{{ */
ZEND_HASH_FOREACH_VAL(src, src_entry) {
if (UNEXPECTED(Z_ISREF_P(src_entry)) &&
UNEXPECTED(Z_REFCOUNT_P(src_entry) == 1)) {
- ZVAL_UNREF(src_entry);
+ src_entry = Z_REFVAL_P(src_entry);
}
Z_TRY_ADDREF_P(src_entry);
ZEND_HASH_FILL_ADD(src_entry);
@@ -3735,7 +3735,7 @@ PHPAPI int php_array_merge(HashTable *dest, HashTable *src) /* {{{ */
ZEND_HASH_FOREACH_STR_KEY_VAL(src, string_key, src_entry) {
if (UNEXPECTED(Z_ISREF_P(src_entry) &&
Z_REFCOUNT_P(src_entry) == 1)) {
- ZVAL_UNREF(src_entry);
+ src_entry = Z_REFVAL_P(src_entry);
}
Z_TRY_ADDREF_P(src_entry);
if (string_key) {
@@ -3883,7 +3883,7 @@ static inline void php_array_merge_or_replace_wrapper(INTERNAL_FUNCTION_PARAMETE
ZEND_HASH_FOREACH_VAL(src, src_entry) {
if (UNEXPECTED(Z_ISREF_P(src_entry) &&
Z_REFCOUNT_P(src_entry) == 1)) {
- ZVAL_UNREF(src_entry);
+ src_entry = Z_REFVAL_P(src_entry);
}
Z_TRY_ADDREF_P(src_entry);
ZEND_HASH_FILL_ADD(src_entry);
@@ -3895,7 +3895,7 @@ static inline void php_array_merge_or_replace_wrapper(INTERNAL_FUNCTION_PARAMETE
ZEND_HASH_FOREACH_STR_KEY_VAL(src, string_key, src_entry) {
if (UNEXPECTED(Z_ISREF_P(src_entry) &&
Z_REFCOUNT_P(src_entry) == 1)) {
- ZVAL_UNREF(src_entry);
+ src_entry = Z_REFVAL_P(src_entry);
}
Z_TRY_ADDREF_P(src_entry);
if (EXPECTED(string_key)) {
@@ -4285,7 +4285,7 @@ PHP_FUNCTION(array_reverse)
ZEND_HASH_REVERSE_FOREACH_VAL(Z_ARRVAL_P(input), entry) {
if (UNEXPECTED(Z_ISREF_P(entry) &&
Z_REFCOUNT_P(entry) == 1)) {
- ZVAL_UNREF(entry);
+ entry = Z_REFVAL_P(entry);
}
Z_TRY_ADDREF_P(entry);
ZEND_HASH_FILL_ADD(entry);
@@ -4679,7 +4679,7 @@ static void php_array_intersect_key(INTERNAL_FUNCTION_PARAMETERS, int data_compa
if (Z_TYPE_P(val) == IS_UNDEF) continue;
}
if (Z_ISREF_P(val) && Z_REFCOUNT_P(val) == 1) {
- ZVAL_UNREF(val);
+ val = Z_REFVAL_P(val);
}
if (p->key == NULL) {
ok = 1;
@@ -5090,7 +5090,7 @@ static void php_array_diff_key(INTERNAL_FUNCTION_PARAMETERS, int data_compare_ty
if (Z_TYPE_P(val) == IS_UNDEF) continue;
}
if (Z_ISREF_P(val) && Z_REFCOUNT_P(val) == 1) {
- ZVAL_UNREF(val);
+ val = Z_REFVAL_P(val);
}
if (p->key == NULL) {
ok = 1;