mirror of
https://github.com/php/php-src.git
synced 2025-08-18 15:08:55 +02:00
Merge branch 'PHP-7.0'
This commit is contained in:
commit
a1c9bd8803
5 changed files with 102 additions and 15 deletions
|
@ -45,7 +45,7 @@ $done = 0;
|
||||||
$a = [0,1,2,3,4];
|
$a = [0,1,2,3,4];
|
||||||
foreach($a as &$v) {
|
foreach($a as &$v) {
|
||||||
echo "$v\n";
|
echo "$v\n";
|
||||||
if ($done && $v == 3) {
|
if (!$done && $v == 3) {
|
||||||
$done = 1;
|
$done = 1;
|
||||||
array_splice($a, 1, 2, $replacement);
|
array_splice($a, 1, 2, $replacement);
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,6 +83,7 @@ static inline spl_array_object *spl_array_from_obj(zend_object *obj) /* {{{ */ {
|
||||||
#define Z_SPLARRAY_P(zv) spl_array_from_obj(Z_OBJ_P((zv)))
|
#define Z_SPLARRAY_P(zv) spl_array_from_obj(Z_OBJ_P((zv)))
|
||||||
|
|
||||||
static inline HashTable *spl_array_get_hash_table(spl_array_object* intern) { /* {{{ */
|
static inline HashTable *spl_array_get_hash_table(spl_array_object* intern) { /* {{{ */
|
||||||
|
//??? TODO: Delay duplication for arrays; only duplicate for write operations
|
||||||
if (intern->ar_flags & SPL_ARRAY_IS_SELF) {
|
if (intern->ar_flags & SPL_ARRAY_IS_SELF) {
|
||||||
if (!intern->std.properties) {
|
if (!intern->std.properties) {
|
||||||
rebuild_object_properties(&intern->std);
|
rebuild_object_properties(&intern->std);
|
||||||
|
@ -91,8 +92,19 @@ static inline HashTable *spl_array_get_hash_table(spl_array_object* intern) { /*
|
||||||
} else if (intern->ar_flags & SPL_ARRAY_USE_OTHER) {
|
} else if (intern->ar_flags & SPL_ARRAY_USE_OTHER) {
|
||||||
spl_array_object *other = Z_SPLARRAY_P(&intern->array);
|
spl_array_object *other = Z_SPLARRAY_P(&intern->array);
|
||||||
return spl_array_get_hash_table(other);
|
return spl_array_get_hash_table(other);
|
||||||
|
} else if (Z_TYPE(intern->array) == IS_ARRAY) {
|
||||||
|
return Z_ARRVAL(intern->array);
|
||||||
} else {
|
} else {
|
||||||
return HASH_OF(&intern->array);
|
zend_object *obj = Z_OBJ(intern->array);
|
||||||
|
if (!obj->properties) {
|
||||||
|
rebuild_object_properties(obj);
|
||||||
|
} else if (GC_REFCOUNT(obj->properties) > 1) {
|
||||||
|
if (EXPECTED(!(GC_FLAGS(obj->properties) & IS_ARRAY_IMMUTABLE))) {
|
||||||
|
GC_REFCOUNT(obj->properties)--;
|
||||||
|
}
|
||||||
|
obj->properties = zend_array_dup(obj->properties);
|
||||||
|
}
|
||||||
|
return obj->properties;
|
||||||
}
|
}
|
||||||
} /* }}} */
|
} /* }}} */
|
||||||
|
|
||||||
|
@ -1082,13 +1094,13 @@ static void spl_array_set_array(zval *object, spl_array_object *intern, zval *ar
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
zval_ptr_dtor(&intern->array);
|
|
||||||
|
|
||||||
if (Z_TYPE_P(array) == IS_ARRAY) {
|
if (Z_TYPE_P(array) == IS_ARRAY) {
|
||||||
//??? TODO: try to avoid array duplication
|
//??? TODO: try to avoid array duplication
|
||||||
|
zval_ptr_dtor(&intern->array);
|
||||||
ZVAL_DUP(&intern->array, array);
|
ZVAL_DUP(&intern->array, array);
|
||||||
} else {
|
} else {
|
||||||
if (Z_OBJ_HT_P(array) == &spl_handler_ArrayObject || Z_OBJ_HT_P(array) == &spl_handler_ArrayIterator) {
|
if (Z_OBJ_HT_P(array) == &spl_handler_ArrayObject || Z_OBJ_HT_P(array) == &spl_handler_ArrayIterator) {
|
||||||
|
zval_ptr_dtor(&intern->array);
|
||||||
if (just_array) {
|
if (just_array) {
|
||||||
spl_array_object *other = Z_SPLARRAY_P(array);
|
spl_array_object *other = Z_SPLARRAY_P(array);
|
||||||
ar_flags = other->ar_flags & ~SPL_ARRAY_INT_MASK;
|
ar_flags = other->ar_flags & ~SPL_ARRAY_INT_MASK;
|
||||||
|
@ -1102,18 +1114,13 @@ static void spl_array_set_array(zval *object, spl_array_object *intern, zval *ar
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
zend_object_get_properties_t handler = Z_OBJ_HANDLER_P(array, get_properties);
|
zend_object_get_properties_t handler = Z_OBJ_HANDLER_P(array, get_properties);
|
||||||
if (handler != std_object_handlers.get_properties
|
if (handler != std_object_handlers.get_properties) {
|
||||||
|| !spl_array_get_hash_table(intern)) {
|
zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0,
|
||||||
ZVAL_UNDEF(&intern->array);
|
"Overloaded object of type %s is not compatible with %s",
|
||||||
zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0, "Overloaded object of type %s is not compatible with %s", Z_OBJCE_P(array)->name, intern->std.ce->name);
|
ZSTR_VAL(Z_OBJCE_P(array)->name), ZSTR_VAL(intern->std.ce->name));
|
||||||
}
|
return;
|
||||||
//??? TODO: try to avoid array duplication
|
|
||||||
if (Z_OBJ_P(array)->properties && GC_REFCOUNT(Z_OBJ_P(array)->properties) > 1) {
|
|
||||||
if (EXPECTED(!(GC_FLAGS(Z_OBJ_P(array)->properties) & IS_ARRAY_IMMUTABLE))) {
|
|
||||||
GC_REFCOUNT(Z_OBJ_P(array)->properties)--;
|
|
||||||
}
|
|
||||||
Z_OBJ_P(array)->properties = zend_array_dup(Z_OBJ_P(array)->properties);
|
|
||||||
}
|
}
|
||||||
|
zval_ptr_dtor(&intern->array);
|
||||||
ZVAL_COPY(&intern->array, array);
|
ZVAL_COPY(&intern->array, array);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1267,6 +1274,11 @@ SPL_METHOD(Array, exchangeArray)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (intern->nApplyCount > 0) {
|
||||||
|
zend_error(E_WARNING, "Modification of ArrayObject during sorting is prohibited");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
RETVAL_ARR(zend_array_dup(spl_array_get_hash_table(intern)));
|
RETVAL_ARR(zend_array_dup(spl_array_get_hash_table(intern)));
|
||||||
spl_array_set_array(object, intern, array, 0L, 1);
|
spl_array_set_array(object, intern, array, 0L, 1);
|
||||||
}
|
}
|
||||||
|
|
29
ext/spl/tests/ArrayObject_exchange_array_during_sorting.phpt
Normal file
29
ext/spl/tests/ArrayObject_exchange_array_during_sorting.phpt
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
--TEST--
|
||||||
|
Can't use exchangeArray() while ArrayObject is being sorted
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
|
||||||
|
$ao = new ArrayObject([1, 2, 3]);
|
||||||
|
$i = 0;
|
||||||
|
$ao->uasort(function($a, $b) use ($ao, &$i) {
|
||||||
|
if ($i++ == 0) {
|
||||||
|
$ao->exchangeArray([4, 5, 6]);
|
||||||
|
var_dump($ao);
|
||||||
|
}
|
||||||
|
return $a <=> $b;
|
||||||
|
});
|
||||||
|
|
||||||
|
?>
|
||||||
|
--EXPECTF--
|
||||||
|
Warning: Modification of ArrayObject during sorting is prohibited in %s on line %d
|
||||||
|
object(ArrayObject)#1 (1) {
|
||||||
|
["storage":"ArrayObject":private]=>
|
||||||
|
array(3) {
|
||||||
|
[0]=>
|
||||||
|
int(1)
|
||||||
|
[1]=>
|
||||||
|
int(2)
|
||||||
|
[2]=>
|
||||||
|
int(3)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
--TEST--
|
||||||
|
Modifications to ArrayObjects should not affect shared properties tables
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
|
||||||
|
$obj = (object)['a' => 1, 'b' => 2];
|
||||||
|
$ao = new ArrayObject($obj);
|
||||||
|
$arr = (array) $obj;
|
||||||
|
$ao['a'] = 42;
|
||||||
|
var_dump($arr);
|
||||||
|
|
||||||
|
?>
|
||||||
|
--EXPECT--
|
||||||
|
array(2) {
|
||||||
|
["a"]=>
|
||||||
|
int(1)
|
||||||
|
["b"]=>
|
||||||
|
int(2)
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
--TEST--
|
||||||
|
Objects with overloaded get_properties are incompatible with ArrayObject
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
|
||||||
|
$ao = new ArrayObject([1, 2, 3]);
|
||||||
|
try {
|
||||||
|
$ao->exchangeArray(new SplFixedArray);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
echo $e->getMessage(), "\n";
|
||||||
|
}
|
||||||
|
var_dump($ao);
|
||||||
|
|
||||||
|
?>
|
||||||
|
--EXPECT--
|
||||||
|
Overloaded object of type SplFixedArray is not compatible with ArrayObject
|
||||||
|
object(ArrayObject)#1 (1) {
|
||||||
|
["storage":"ArrayObject":private]=>
|
||||||
|
array(3) {
|
||||||
|
[0]=>
|
||||||
|
int(1)
|
||||||
|
[1]=>
|
||||||
|
int(2)
|
||||||
|
[2]=>
|
||||||
|
int(3)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue