Commit: 7ccd5943924fd4ad9adcad1fbc547adc79114bff Author: Xinchen Hui <larue...@php.net> Sun, 6 May 2012 20:01:10 +0800 Parents: 304ac568c56799e60d90fadad3a936b61cab281b Branches: PHP-5.3
Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=7ccd5943924fd4ad9adcad1fbc547adc79114bff Log: Fixed bug #61730 (Segfault from array_walk modifying an array passed by reference) Bugs: https://bugs.php.net/61730 Changed paths: M NEWS M ext/standard/array.c A ext/standard/tests/bug61730.phpt Diff: diff --git a/NEWS b/NEWS index 0d42b0f..c2b10e5 100644 --- a/NEWS +++ b/NEWS @@ -11,6 +11,8 @@ PHP NEWS (Laruence) - Core: + . Fixed bug #61730 (Segfault from array_walk modifying an array passed by + reference). (Laruence) . Fixed missing bound check in iptcparse(). (chris at chiappa.net) . Fixed bug #61764 ('I' unpacks n as signed if n > 2^31-1 on LP64). (Gustavo) . Fixed bug #54197 ([PATH=] sections incompatibility with user_ini.filename diff --git a/ext/standard/array.c b/ext/standard/array.c index 9956d00..e804ff8 100644 --- a/ext/standard/array.c +++ b/ext/standard/array.c @@ -1052,7 +1052,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; @@ -1061,15 +1060,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; @@ -1101,7 +1099,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; @@ -1129,7 +1127,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 0000000..0fe9f22 --- /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 +) -- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php