helly           Mon Mar 21 15:07:33 2005 EDT

  Added files:                 
    /php-src/ext/spl/tests      bug32394.phpt 

  Modified files:              
    /php-src/ext/spl    spl_array.c 
  Log:
  - Fix Bug #32394 offsetUnset() segfaults in a foreach
  
  
http://cvs.php.net/diff.php/php-src/ext/spl/spl_array.c?r1=1.65&r2=1.66&ty=u
Index: php-src/ext/spl/spl_array.c
diff -u php-src/ext/spl/spl_array.c:1.65 php-src/ext/spl/spl_array.c:1.66
--- php-src/ext/spl/spl_array.c:1.65    Sun Mar 13 11:35:01 2005
+++ php-src/ext/spl/spl_array.c Mon Mar 21 15:07:31 2005
@@ -16,7 +16,7 @@
    +----------------------------------------------------------------------+
  */
 
-/* $Id: spl_array.c,v 1.65 2005/03/13 16:35:01 helly Exp $ */
+/* $Id: spl_array.c,v 1.66 2005/03/21 20:07:31 helly Exp $ */
 
 #ifdef HAVE_CONFIG_H
 # include "config.h"
@@ -134,6 +134,27 @@
        zend_function *   fptr_offset_del;
 } spl_array_object;
 
+SPL_API int spl_hash_verify_pos(spl_array_object * intern TSRMLS_DC) /* {{{ */
+{
+       HashTable *ht = HASH_OF(intern->array);
+       Bucket *p;
+
+/*     IS_CONSISTENT(ht);*/
+
+/*     HASH_PROTECT_RECURSION(ht);*/
+       p = ht->pListHead;
+       while (p != NULL) {
+               if (p == intern->pos) {
+                       return SUCCESS;
+               }
+               p = p->pListNext;
+       }
+/*     HASH_UNPROTECT_RECURSION(ht); */
+       zend_hash_internal_pointer_reset_ex(HASH_OF(intern->array), 
&intern->pos);
+       return FAILURE;
+}
+/* }}} */
+
 /* {{{ spl_array_object_free_storage */
 static void spl_array_object_free_storage(void *object TSRMLS_DC)
 {
@@ -352,7 +373,7 @@
                                zend_error(E_NOTICE,"Undefined index:  %s", 
Z_STRVAL_P(offset));
                        }
                }
-               return;
+               break;
        case IS_DOUBLE:
        case IS_RESOURCE:
        case IS_BOOL: 
@@ -365,11 +386,12 @@
                if (zend_hash_index_del(HASH_OF(intern->array), index) == 
FAILURE) {
                        zend_error(E_NOTICE,"Undefined offset:  %ld", 
Z_LVAL_P(offset));
                }
-               return;
+               break;
        default:
                zend_error(E_WARNING, "Illegal offset type");
                return;
        }
+       spl_hash_verify_pos(intern TSRMLS_CC); /* call rewind on FAILURE */
 } /* }}} */
 
 static void spl_array_unset_dimension(zval *object, zval *offset TSRMLS_DC) /* 
{{{ */
@@ -521,27 +543,6 @@
 }
 /* }}} */
 
-SPL_API int spl_hash_verify_pos(spl_array_object * intern TSRMLS_DC) /* {{{ */
-{
-       HashTable *ht = HASH_OF(intern->array);
-       Bucket *p;
-
-/*     IS_CONSISTENT(ht);*/
-
-/*     HASH_PROTECT_RECURSION(ht);*/
-       p = ht->pListHead;
-       while (p != NULL) {
-               if (p == intern->pos) {
-                       return SUCCESS;
-               }
-               p = p->pListNext;
-       }
-/*     HASH_UNPROTECT_RECURSION(ht); */
-       zend_hash_internal_pointer_reset_ex(HASH_OF(intern->array), 
&intern->pos);
-       return FAILURE;
-}
-/* }}} */
-
 static int spl_array_skip_protected(spl_array_object *intern TSRMLS_DC) /* {{{ 
*/
 {
        char *string_key;
@@ -673,19 +674,26 @@
 }
 /* }}} */
 
-static void spl_array_it_rewind(zend_object_iterator *iter TSRMLS_DC) /* {{{ */
+static void spl_array_rewind(spl_array_object *intern TSRMLS_DC) /* {{{ */
 {
-       spl_array_it       *iterator = (spl_array_it *)iter;
-       spl_array_object   *object   = iterator->object;
-       HashTable          *aht      = HASH_OF(object->array);
+       HashTable          *aht      = HASH_OF(intern->array);
 
        if (!aht) {
                php_error_docref(NULL TSRMLS_CC, E_NOTICE, 
"ArrayIterator::rewind(): Array was modified outside object and is no longer an 
array");
                return;
        }
 
-       zend_hash_internal_pointer_reset_ex(aht, &object->pos);
-       spl_array_skip_protected(object TSRMLS_CC);
+       zend_hash_internal_pointer_reset_ex(aht, &intern->pos);
+       spl_array_skip_protected(intern TSRMLS_CC);
+}
+/* }}} */
+
+static void spl_array_it_rewind(zend_object_iterator *iter TSRMLS_DC) /* {{{ */
+{
+       spl_array_it       *iterator = (spl_array_it *)iter;
+       spl_array_object   *object   = iterator->object;
+
+       spl_array_rewind(object TSRMLS_CC);
 }
 /* }}} */
 
@@ -782,15 +790,8 @@
 {
        zval *object = getThis();
        spl_array_object *intern = 
(spl_array_object*)zend_object_store_get_object(object TSRMLS_CC);
-       HashTable *aht = HASH_OF(intern->array);
-
-       if (!aht) {
-               php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Array was modified 
outside object and is no longer an array");
-               return;
-       }
 
-       zend_hash_internal_pointer_reset_ex(aht, &intern->pos);
-       spl_array_skip_protected(intern TSRMLS_CC);
+       spl_array_rewind(intern TSRMLS_CC);
 }
 /* }}} */
 

http://cvs.php.net/co.php/php-src/ext/spl/tests/bug32394.phpt?r=1.1&p=1
Index: php-src/ext/spl/tests/bug32394.phpt
+++ php-src/ext/spl/tests/bug32394.phpt
--TEST--
Bug #32394 (offsetUnset() segfaults in a foreach)
--FILE--
<?php

$object = new ArrayIterator;
$object->append(1);

foreach($object as $key => $value)
{
        $object->offsetUnset($key);
}

?>
===DONE===
--EXPECT--
===DONE===

-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to