diff --git a/ext/json/json_encoder.c b/ext/json/json_encoder.c index 1fa234420416a..5ed048f37a9fd 100644 --- a/ext/json/json_encoder.c +++ b/ext/json/json_encoder.c @@ -483,6 +483,14 @@ static int php_json_encode_serializable_object(smart_str *buf, zval *val, int op } if ((Z_TYPE(retval) == IS_OBJECT) && + (Z_OBJ(retval) != Z_OBJ_P(val)) && + ce->name == Z_OBJCE(retval)->name) { + zend_throw_exception_ex(NULL, 0, "%s::jsonSerialize() cannot return a new instance of itself", ZSTR_VAL(ce->name)); + zval_ptr_dtor(&retval); + zval_ptr_dtor(&fname); + PHP_JSON_HASH_APPLY_PROTECTION_DEC(myht); + return FAILURE; + } else if ((Z_TYPE(retval) == IS_OBJECT) && (Z_OBJ(retval) == Z_OBJ_P(val))) { /* Handle the case where jsonSerialize does: return $this; by going straight to encode array */ PHP_JSON_HASH_APPLY_PROTECTION_DEC(myht); diff --git a/ext/json/tests/bug75237.phpt b/ext/json/tests/bug75237.phpt new file mode 100644 index 0000000000000..6c1a7a9e809d9 --- /dev/null +++ b/ext/json/tests/bug75237.phpt @@ -0,0 +1,20 @@ +--TEST-- +Bug #75237 (jsonSerialize() - Returning new instance of self causes segfault) +--SKIPIF-- + +--FILE-- +getMessage(); +} +?> +--EXPECT-- +Foo::jsonSerialize() cannot return a new instance of itself