com php-src: Fixed passing arguments by reference into array_walk() callbacks.: ext/standard/array.c
| From: | Dmitry Stogov | Date: | Mon, 14 Apr 2014 11:11:05 +0000 |
| Subject: | com php-src: Fixed passing arguments by reference into array_walk() callbacks.: ext/standard/array.c | ||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-77413@lists.php.net to get a copy of this message | ||
Commit: 703c1bc570d1fc9a379fa38b298d6759a4b1a687
Author: Dmitry Stogov <dmitry@zend.com> Mon, 14 Apr 2014 15:11:05 +0400
Parents: 5dc52e488048d93767b78fe7fce34a6a0febc5e0
Branches: phpng
Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=703c1bc570d1fc9a379fa38b298d6759a4b1a687
Log:
Fixed passing arguments by reference into array_walk() callbacks.
Changed paths:
M ext/standard/array.c
Diff:
diff --git a/ext/standard/array.c b/ext/standard/array.c
index 4f32345..bef42fe 100644
--- a/ext/standard/array.c
+++ b/ext/standard/array.c
@@ -1081,23 +1081,21 @@ static int php_array_walk(HashTable *target_hash, zval *userdata, int
recursive
continue;
}
}
- ZVAL_COPY(&args[0], zv);
if (recursive &&
- (Z_TYPE(args[0]) == IS_ARRAY ||
- (Z_ISREF(args[0]) && Z_TYPE_P(Z_REFVAL(args[0])) == IS_ARRAY))) {
+ (Z_TYPE_P(zv) == IS_ARRAY ||
+ (Z_ISREF_P(zv) && Z_TYPE_P(Z_REFVAL_P(zv)) == IS_ARRAY))) {
HashTable *thash;
zend_fcall_info orig_array_walk_fci;
zend_fcall_info_cache orig_array_walk_fci_cache;
- if (Z_ISREF(args[0])) {
- thash = Z_ARRVAL_P(Z_REFVAL(args[0]));
+ if (Z_ISREF_P(zv)) {
+ thash = Z_ARRVAL_P(Z_REFVAL_P(zv));
} else {
- SEPARATE_ZVAL(&args[0]);
- thash = Z_ARRVAL(args[0]);
+ SEPARATE_ZVAL(zv);
+ thash = Z_ARRVAL_P(zv);
}
if (thash->nApplyCount > 1) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "recursion detected");
- zval_ptr_dtor(&args[0]);
if (userdata) {
zval_ptr_dtor(&args[2]);
}
@@ -1116,11 +1114,25 @@ static int php_array_walk(HashTable *target_hash, zval *userdata, int
recursive
BG(array_walk_fci) = orig_array_walk_fci;
BG(array_walk_fci_cache) = orig_array_walk_fci_cache;
} else {
+ int was_ref = Z_ISREF_P(zv);
+
+ ZVAL_COPY(&args[0], zv);
+
/* Allocate space for key */
zend_hash_get_current_key_zval(target_hash, &args[1]);
/* Call the userland function */
if (zend_call_function(&BG(array_walk_fci), &BG(array_walk_fci_cache) TSRMLS_CC) ==
SUCCESS) {
+ if (!was_ref && Z_ISREF(args[0])) {
+ /* copy reference back */
+ zval garbage;
+
+ ZVAL_COPY_VALUE(&garbage, zv);
+ ZVAL_COPY_VALUE(zv, &args[0]);
+ zval_ptr_dtor(&garbage);
+ } else {
+ zval_ptr_dtor(&args[0]);
+ }
zval_ptr_dtor(&retval);
} else {
zval_ptr_dtor(&args[0]);
@@ -1132,7 +1144,6 @@ static int php_array_walk(HashTable *target_hash, zval *userdata, int
recursive
}
}
- zval_ptr_dtor(&args[0]);
if (Z_TYPE(args[1]) != IS_UNDEF) {
zval_ptr_dtor(&args[1]);
ZVAL_UNDEF(&args[1]);