mirror of
https://github.com/php/php-src.git
synced 2025-08-20 09:24:05 +02:00
- Fix Bug #32394 offsetUnset() segfaults in a foreach
This commit is contained in:
parent
756c5784c1
commit
041524feee
2 changed files with 55 additions and 37 deletions
|
@ -134,6 +134,27 @@ typedef struct _spl_array_object {
|
||||||
zend_function * fptr_offset_del;
|
zend_function * fptr_offset_del;
|
||||||
} spl_array_object;
|
} 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 */
|
/* {{{ spl_array_object_free_storage */
|
||||||
static void spl_array_object_free_storage(void *object TSRMLS_DC)
|
static void spl_array_object_free_storage(void *object TSRMLS_DC)
|
||||||
{
|
{
|
||||||
|
@ -352,7 +373,7 @@ static void spl_array_unset_dimension_ex(int check_inherited, zval *object, zval
|
||||||
zend_error(E_NOTICE,"Undefined index: %s", Z_STRVAL_P(offset));
|
zend_error(E_NOTICE,"Undefined index: %s", Z_STRVAL_P(offset));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
break;
|
||||||
case IS_DOUBLE:
|
case IS_DOUBLE:
|
||||||
case IS_RESOURCE:
|
case IS_RESOURCE:
|
||||||
case IS_BOOL:
|
case IS_BOOL:
|
||||||
|
@ -365,11 +386,12 @@ static void spl_array_unset_dimension_ex(int check_inherited, zval *object, zval
|
||||||
if (zend_hash_index_del(HASH_OF(intern->array), index) == FAILURE) {
|
if (zend_hash_index_del(HASH_OF(intern->array), index) == FAILURE) {
|
||||||
zend_error(E_NOTICE,"Undefined offset: %ld", Z_LVAL_P(offset));
|
zend_error(E_NOTICE,"Undefined offset: %ld", Z_LVAL_P(offset));
|
||||||
}
|
}
|
||||||
return;
|
break;
|
||||||
default:
|
default:
|
||||||
zend_error(E_WARNING, "Illegal offset type");
|
zend_error(E_WARNING, "Illegal offset type");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
spl_hash_verify_pos(intern TSRMLS_CC); /* call rewind on FAILURE */
|
||||||
} /* }}} */
|
} /* }}} */
|
||||||
|
|
||||||
static void spl_array_unset_dimension(zval *object, zval *offset TSRMLS_DC) /* {{{ */
|
static void spl_array_unset_dimension(zval *object, zval *offset TSRMLS_DC) /* {{{ */
|
||||||
|
@ -521,27 +543,6 @@ static HashTable *spl_array_get_properties(zval *object TSRMLS_DC)
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
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) /* {{{ */
|
static int spl_array_skip_protected(spl_array_object *intern TSRMLS_DC) /* {{{ */
|
||||||
{
|
{
|
||||||
char *string_key;
|
char *string_key;
|
||||||
|
@ -673,19 +674,26 @@ static void spl_array_it_move_forward(zend_object_iterator *iter TSRMLS_DC) /* {
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
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;
|
HashTable *aht = HASH_OF(intern->array);
|
||||||
spl_array_object *object = iterator->object;
|
|
||||||
HashTable *aht = HASH_OF(object->array);
|
|
||||||
|
|
||||||
if (!aht) {
|
if (!aht) {
|
||||||
php_error_docref(NULL TSRMLS_CC, E_NOTICE, "ArrayIterator::rewind(): Array was modified outside object and is no longer an array");
|
php_error_docref(NULL TSRMLS_CC, E_NOTICE, "ArrayIterator::rewind(): Array was modified outside object and is no longer an array");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
zend_hash_internal_pointer_reset_ex(aht, &object->pos);
|
zend_hash_internal_pointer_reset_ex(aht, &intern->pos);
|
||||||
spl_array_skip_protected(object TSRMLS_CC);
|
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 @@ SPL_METHOD(Array, rewind)
|
||||||
{
|
{
|
||||||
zval *object = getThis();
|
zval *object = getThis();
|
||||||
spl_array_object *intern = (spl_array_object*)zend_object_store_get_object(object TSRMLS_CC);
|
spl_array_object *intern = (spl_array_object*)zend_object_store_get_object(object TSRMLS_CC);
|
||||||
HashTable *aht = HASH_OF(intern->array);
|
|
||||||
|
|
||||||
if (!aht) {
|
spl_array_rewind(intern TSRMLS_CC);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
|
17
ext/spl/tests/bug32394.phpt
Executable file
17
ext/spl/tests/bug32394.phpt
Executable file
|
@ -0,0 +1,17 @@
|
||||||
|
--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===
|
Loading…
Add table
Add a link
Reference in a new issue