summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXinchen Hui <laruence@php.net>2012-05-06 20:06:05 +0800
committerXinchen Hui <laruence@php.net>2012-05-06 20:28:18 +0800
commit4cceeb25b74eb89ff8d4106d1b195a1c18fc94d8 (patch)
treefba464867d158e98236dd6c1f524773552fdca87
parentbef6111609bc05ae99f9392e507a47ae09ef72f9 (diff)
parent7ccd5943924fd4ad9adcad1fbc547adc79114bff (diff)
downloadphp-git-4cceeb25b74eb89ff8d4106d1b195a1c18fc94d8.tar.gz
Merge branch 'PHP-5.3' into PHP-5.4
* PHP-5.3: Fixed bug #61730 (Segfault from array_walk modifying an array passed by reference)
-rw-r--r--NEWS2
-rw-r--r--ext/standard/array.c12
-rw-r--r--ext/standard/tests/bug61730.phpt37
3 files changed, 44 insertions, 7 deletions
diff --git a/NEWS b/NEWS
index 8b82237849..f88bf70aec 100644
--- a/NEWS
+++ b/NEWS
@@ -14,6 +14,8 @@ PHP NEWS
(Laruence)
- Core:
+ . Fixed bug #61730 (Segfault from array_walk modifying an array passed by
+ reference). (Laruence)
. Fixed bug #61922 (ZTS build doesn't accept zend.script_encoding config).
(Laruence)
. Fixed missing bound check in iptcparse(). (chris at chiappa.net)
diff --git a/ext/standard/array.c b/ext/standard/array.c
index d1f302994f..94c5e7e6ee 100644
--- a/ext/standard/array.c
+++ b/ext/standard/array.c
@@ -1058,7 +1058,6 @@ static int php_array_walk(HashTable *target_hash, zval *userdata, int recursive
char *string_key;
uint string_key_len;
ulong num_key;
- HashPosition pos;
/* Set up known arguments */
args[1] = &key;
@@ -1067,15 +1066,14 @@ static int php_array_walk(HashTable *target_hash, zval *userdata, int recursive
Z_ADDREF_P(userdata);
}
- zend_hash_internal_pointer_reset_ex(target_hash, &pos);
-
BG(array_walk_fci).retval_ptr_ptr = &retval_ptr;
BG(array_walk_fci).param_count = userdata ? 3 : 2;
BG(array_walk_fci).params = args;
BG(array_walk_fci).no_separation = 0;
-
+
/* Iterate through hash */
- while (!EG(exception) && zend_hash_get_current_data_ex(target_hash, (void **)&args[0], &pos) == SUCCESS) {
+ zend_hash_internal_pointer_reset(target_hash);
+ while (!EG(exception) && zend_hash_get_current_data(target_hash, (void **)&args[0]) == SUCCESS) {
if (recursive && Z_TYPE_PP(args[0]) == IS_ARRAY) {
HashTable *thash;
zend_fcall_info orig_array_walk_fci;
@@ -1107,7 +1105,7 @@ static int php_array_walk(HashTable *target_hash, zval *userdata, int recursive
MAKE_STD_ZVAL(key);
/* Set up the key */
- switch (zend_hash_get_current_key_ex(target_hash, &string_key, &string_key_len, &num_key, 0, &pos)) {
+ switch (zend_hash_get_current_key_ex(target_hash, &string_key, &string_key_len, &num_key, 0, NULL)) {
case HASH_KEY_IS_LONG:
Z_TYPE_P(key) = IS_LONG;
Z_LVAL_P(key) = num_key;
@@ -1135,7 +1133,7 @@ static int php_array_walk(HashTable *target_hash, zval *userdata, int recursive
zval_ptr_dtor(&key);
key = NULL;
}
- zend_hash_move_forward_ex(target_hash, &pos);
+ zend_hash_move_forward(target_hash);
}
if (userdata) {
diff --git a/ext/standard/tests/bug61730.phpt b/ext/standard/tests/bug61730.phpt
new file mode 100644
index 0000000000..0fe9f22212
--- /dev/null
+++ b/ext/standard/tests/bug61730.phpt
@@ -0,0 +1,37 @@
+--TEST--
+Bug #61730 (Segfault from array_walk modifying an array passed by reference)
+--FILE--
+<?php
+$myArray = array_fill(0, 10, 1);
+
+array_walk(
+ $myArray,
+ function($value, $key) use ($myArray)
+ {
+ reset($myArray);
+ }
+);
+
+array_walk(
+ $myArray,
+ function($value, $key) use (&$myArray)
+ {
+ var_dump($key);
+ unset($myArray[$key]);
+ unset($myArray[$key+1]);
+ unset($myArray[$key+2]);
+ }
+);
+
+
+
+print_r($myArray);
+--EXPECT--
+int(0)
+int(4)
+int(8)
+Array
+(
+ [3] => 1
+ [7] => 1
+)