diff --git a/Zend/tests/gh14969.phpt b/Zend/tests/gh14969.phpt new file mode 100644 index 0000000000000..dedbaa7456e00 --- /dev/null +++ b/Zend/tests/gh14969.phpt @@ -0,0 +1,47 @@ +--TEST-- +GH-14969: Crash on coercion with throwing __toString() +--FILE-- +prop = $c; +} catch (Throwable $e) { + echo $e->getMessage(), "\n"; +} +var_dump($d); + +$c = new C(); +$d->prop = 'foo'; +try { + $d->prop = $c; +} catch (Throwable $e) { + echo $e->getMessage(), "\n"; +} +var_dump($d); + +?> +--EXPECTF-- +C::__toString +object(D)#%d (0) { + ["prop"]=> + uninitialized(string) +} +C::__toString +object(D)#2 (1) { + ["prop"]=> + string(3) "foo" +} diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index 58301da038ce0..d4586e53e4b4a 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -819,7 +819,7 @@ ZEND_API zval *zend_std_write_property(zend_object *zobj, zend_string *name, zva ZVAL_COPY_VALUE(&tmp, value); if (UNEXPECTED(!zend_verify_property_type(prop_info, &tmp, property_uses_strict_types()))) { - Z_TRY_DELREF_P(value); + zval_ptr_dtor(&tmp); variable_ptr = &EG(error_zval); goto exit; } @@ -890,7 +890,7 @@ ZEND_API zval *zend_std_write_property(zend_object *zobj, zend_string *name, zva ZVAL_COPY_VALUE(&tmp, value); if (UNEXPECTED(!zend_verify_property_type(prop_info, &tmp, property_uses_strict_types()))) { - zval_ptr_dtor(value); + zval_ptr_dtor(&tmp); goto exit; } value = &tmp;