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

Reply via email to