mirror of
https://github.com/php/php-src.git
synced 2025-08-15 21:48:51 +02:00
Fixed segfault (Zend/tests/026.phpt now pass)
This commit is contained in:
parent
ff61b46941
commit
b917458490
5 changed files with 55 additions and 50 deletions
|
@ -754,19 +754,23 @@ static inline void zend_assign_to_object(zval *retval, zval *object, zval *prope
|
|||
if (Z_TYPE_P(object) == IS_NULL ||
|
||||
(Z_TYPE_P(object) == IS_BOOL && Z_LVAL_P(object) == 0) ||
|
||||
(Z_TYPE_P(object) == IS_STRING && Z_STRLEN_P(object) == 0)) {
|
||||
SEPARATE_ZVAL_IF_NOT_REF(object);
|
||||
Z_ADDREF_P(object);
|
||||
zend_error(E_WARNING, "Creating default object from empty value");
|
||||
if (Z_REFCOUNTED_P(object) && Z_REFCOUNT_P(object) == 1) {
|
||||
/* object was removed by error handler, nothing to assign to */
|
||||
zval_ptr_dtor(object);
|
||||
if (retval) {
|
||||
ZVAL_NULL(retval);
|
||||
if (Z_REFCOUNTED_P(object)) {
|
||||
SEPARATE_ZVAL_IF_NOT_REF(object);
|
||||
Z_ADDREF_P(object);
|
||||
zend_error(E_WARNING, "Creating default object from empty value");
|
||||
if (Z_REFCOUNT_P(object) == 1) {
|
||||
/* object was removed by error handler, nothing to assign to */
|
||||
zval_ptr_dtor(object);
|
||||
if (retval) {
|
||||
ZVAL_NULL(retval);
|
||||
}
|
||||
FREE_OP(free_value);
|
||||
return;
|
||||
}
|
||||
FREE_OP(free_value);
|
||||
return;
|
||||
Z_DELREF_P(object);
|
||||
} else {
|
||||
zend_error(E_WARNING, "Creating default object from empty value");
|
||||
}
|
||||
Z_DELREF_P(object);
|
||||
zval_dtor(object);
|
||||
object_init(object);
|
||||
} else {
|
||||
|
|
|
@ -545,38 +545,39 @@ ZEND_API void zend_std_write_property(zval *object, zval *member, zval *value, c
|
|||
variable_ptr = &zobj->properties_table[property_info->offset];
|
||||
goto found;
|
||||
}
|
||||
if (UNEXPECTED(!zobj->properties)) {
|
||||
variable_ptr = zend_hash_find(zobj->properties, property_info->name);
|
||||
if (EXPECTED(zobj->properties != NULL)) {
|
||||
if ((variable_ptr = zend_hash_find(zobj->properties, property_info->name)) != NULL) {
|
||||
found:
|
||||
/* if we already have this value there, we don't actually need to do anything */
|
||||
if (EXPECTED(variable_ptr != value)) {
|
||||
/* if we are assigning reference, we shouldn't move it, but instead assign variable
|
||||
to the same pointer */
|
||||
if (Z_ISREF_P(variable_ptr)) {
|
||||
zval garbage;
|
||||
/* if we already have this value there, we don't actually need to do anything */
|
||||
if (EXPECTED(variable_ptr != value)) {
|
||||
/* if we are assigning reference, we shouldn't move it, but instead assign variable
|
||||
to the same pointer */
|
||||
if (Z_ISREF_P(variable_ptr)) {
|
||||
zval garbage;
|
||||
|
||||
ZVAL_COPY_VALUE(&garbage, Z_REFVAL_P(variable_ptr)); /* old value should be destroyed */
|
||||
ZVAL_COPY_VALUE(&garbage, Z_REFVAL_P(variable_ptr)); /* old value should be destroyed */
|
||||
|
||||
/* To check: can't *variable_ptr be some system variable like error_zval here? */
|
||||
ZVAL_COPY_VALUE(Z_REFVAL_P(variable_ptr), value);
|
||||
if (Z_REFCOUNT_P(value) > 0) {
|
||||
zval_copy_ctor(Z_REFVAL_P(variable_ptr));
|
||||
}
|
||||
zval_dtor(&garbage);
|
||||
} else {
|
||||
zval garbage;
|
||||
|
||||
ZVAL_COPY_VALUE(&garbage, variable_ptr);
|
||||
|
||||
/* if we assign referenced variable, we should separate it */
|
||||
if (IS_REFCOUNTED(Z_TYPE_P(value))) {
|
||||
Z_ADDREF_P(value);
|
||||
if (Z_ISREF_P(value)) {
|
||||
SEPARATE_ZVAL(value);
|
||||
/* To check: can't *variable_ptr be some system variable like error_zval here? */
|
||||
ZVAL_COPY_VALUE(Z_REFVAL_P(variable_ptr), value);
|
||||
if (Z_REFCOUNT_P(value) > 0) {
|
||||
zval_copy_ctor(Z_REFVAL_P(variable_ptr));
|
||||
}
|
||||
zval_dtor(&garbage);
|
||||
} else {
|
||||
zval garbage;
|
||||
|
||||
ZVAL_COPY_VALUE(&garbage, variable_ptr);
|
||||
|
||||
/* if we assign referenced variable, we should separate it */
|
||||
if (IS_REFCOUNTED(Z_TYPE_P(value))) {
|
||||
Z_ADDREF_P(value);
|
||||
if (Z_ISREF_P(value)) {
|
||||
SEPARATE_ZVAL(value);
|
||||
}
|
||||
}
|
||||
ZVAL_COPY_VALUE(variable_ptr, value);
|
||||
zval_ptr_dtor(&garbage);
|
||||
}
|
||||
ZVAL_COPY_VALUE(variable_ptr, value);
|
||||
zval_ptr_dtor(&garbage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -129,7 +129,7 @@ ZEND_API void zend_objects_store_del(zend_object *object TSRMLS_DC) /* {{{ */
|
|||
*/
|
||||
if (EG(objects_store).object_buckets &&
|
||||
IS_VALID(EG(objects_store).object_buckets[object->handle])) {
|
||||
if (object->gc.refcount == 0) {
|
||||
if (object->gc.refcount == 1) {
|
||||
int failure = 0;
|
||||
|
||||
if (!(object->gc.u.v.flags & IS_OBJ_DESTRUCTOR_CALLED)) {
|
||||
|
@ -146,7 +146,7 @@ ZEND_API void zend_objects_store_del(zend_object *object TSRMLS_DC) /* {{{ */
|
|||
}
|
||||
}
|
||||
|
||||
if (object->gc.refcount == 0) {
|
||||
if (object->gc.refcount == 1) {
|
||||
zend_uint handle = object->handle;
|
||||
|
||||
//??? GC_REMOVE_ZOBJ_FROM_BUFFER(obj);
|
||||
|
|
|
@ -5208,11 +5208,11 @@ ZEND_VM_HANDLER(156, ZEND_SEPARATE, VAR, UNUSED)
|
|||
|
||||
SAVE_OPLINE();
|
||||
var_ptr = EX_VAR(opline->op1.var);
|
||||
if (Z_TYPE_P(var_ptr) != IS_OBJECT &&
|
||||
!Z_ISREF_P(var_ptr) &&
|
||||
Z_REFCOUNT_P(var_ptr) > 1) {
|
||||
|
||||
Z_DELREF_P(var_ptr);
|
||||
if (Z_TYPE_P(var_ptr) != IS_OBJECT && !Z_ISREF_P(var_ptr)) {
|
||||
if (Z_REFCOUNTED_P(var_ptr) &&
|
||||
Z_REFCOUNT_P(var_ptr) > 1) {
|
||||
Z_DELREF_P(var_ptr);
|
||||
}
|
||||
ZVAL_DUP(EX_VAR(opline->op1.var), var_ptr);
|
||||
}
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
|
|
|
@ -20932,11 +20932,11 @@ static int ZEND_FASTCALL ZEND_SEPARATE_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HAND
|
|||
|
||||
SAVE_OPLINE();
|
||||
var_ptr = EX_VAR(opline->op1.var);
|
||||
if (Z_TYPE_P(var_ptr) != IS_OBJECT &&
|
||||
!Z_ISREF_P(var_ptr) &&
|
||||
Z_REFCOUNT_P(var_ptr) > 1) {
|
||||
|
||||
Z_DELREF_P(var_ptr);
|
||||
if (Z_TYPE_P(var_ptr) != IS_OBJECT && !Z_ISREF_P(var_ptr)) {
|
||||
if (Z_REFCOUNTED_P(var_ptr) &&
|
||||
Z_REFCOUNT_P(var_ptr) > 1) {
|
||||
Z_DELREF_P(var_ptr);
|
||||
}
|
||||
ZVAL_DUP(EX_VAR(opline->op1.var), var_ptr);
|
||||
}
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue