mirror of
https://github.com/php/php-src.git
synced 2024-09-22 18:37:25 +00:00
Fix AO object properties separation
This commit is contained in:
parent
079f2f7eb3
commit
0aa7163816
@ -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)))
|
||||
|
||||
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->std.properties) {
|
||||
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) {
|
||||
spl_array_object *other = Z_SPLARRAY_P(&intern->array);
|
||||
return spl_array_get_hash_table(other);
|
||||
} else if (Z_TYPE(intern->array) == IS_ARRAY) {
|
||||
return Z_ARRVAL(intern->array);
|
||||
} 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;
|
||||
}
|
||||
} /* }}} */
|
||||
|
||||
@ -1107,13 +1119,6 @@ static void spl_array_set_array(zval *object, spl_array_object *intern, zval *ar
|
||||
ZVAL_UNDEF(&intern->array);
|
||||
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);
|
||||
}
|
||||
//??? 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_COPY(&intern->array, array);
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
Loading…
Reference in New Issue
Block a user