Skip to content

Commit

Permalink
ext/json: Refactor php_json_encode_serializable_object() to call meth…
Browse files Browse the repository at this point in the history
…od directly
  • Loading branch information
Girgias committed Jan 13, 2025
1 parent 5ef5b68 commit e73e165
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 29 deletions.
6 changes: 6 additions & 0 deletions UPGRADING.INTERNALS
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ PHP 8.5 INTERNALS UPGRADE NOTES
. The gdImageScale*() and gdImageRotate*() helpers are now internal in the
bundled libgd, like they have been in external libgd as of gd-2.1.1.

- ext/json
. php_json_encode_serializable_object() now assumes `EG(active)`,
if not a bailout is caused. Therefore a minor BC break exists if the
`PHP_JSON_PARTIAL_OUTPUT_ON_ERROR` option is in use.
However, this situation is highly unlikely.

- ext/libxml
. The refcount APIs now return an `unsigned int` instead of an `int`.

Expand Down
39 changes: 10 additions & 29 deletions ext/json/json_encoder.c
Original file line number Diff line number Diff line change
Expand Up @@ -579,12 +579,11 @@ zend_result php_json_escape_string(
}
/* }}} */

static zend_result php_json_encode_serializable_object(smart_str *buf, zval *val, int options, php_json_encoder *encoder) /* {{{ */
static zend_result php_json_encode_serializable_object(smart_str *buf, zend_object *obj, int options, php_json_encoder *encoder)
{
zend_class_entry *ce = Z_OBJCE_P(val);
zend_object *obj = Z_OBJ_P(val);
zend_class_entry *ce = obj->ce;
uint32_t *guard = zend_get_recursion_guard(obj);
zval retval, fname;
zval retval;
zend_result return_code;

ZEND_ASSERT(guard != NULL);
Expand All @@ -599,35 +598,19 @@ static zend_result php_json_encode_serializable_object(smart_str *buf, zval *val

ZEND_GUARD_PROTECT_RECURSION(guard, JSON);

ZVAL_STRING(&fname, "jsonSerialize");

if (FAILURE == call_user_function(NULL, val, &fname, &retval, 0, NULL) || Z_TYPE(retval) == IS_UNDEF) {
if (!EG(exception)) {
zend_throw_exception_ex(NULL, 0, "Failed calling %s::jsonSerialize()", ZSTR_VAL(ce->name));
}
zval_ptr_dtor(&fname);

zend_function *json_serialize_method = zend_hash_str_find_ptr(&ce->function_table, ZEND_STRL("jsonserialize"));
ZEND_ASSERT(json_serialize_method != NULL && "This should be guaranteed prior to calling this function");
zend_call_known_function(json_serialize_method, obj, ce, &retval, 0, NULL, NULL);
/* An exception has occurred */
if (Z_TYPE(retval) == IS_UNDEF) {
if (options & PHP_JSON_PARTIAL_OUTPUT_ON_ERROR) {
smart_str_appendl(buf, "null", 4);
}
ZEND_GUARD_UNPROTECT_RECURSION(guard, JSON);
return FAILURE;
}

if (EG(exception)) {
/* Error already raised */
zval_ptr_dtor(&retval);
zval_ptr_dtor(&fname);

if (options & PHP_JSON_PARTIAL_OUTPUT_ON_ERROR) {
smart_str_appendl(buf, "null", 4);
}
ZEND_GUARD_UNPROTECT_RECURSION(guard, JSON);
return FAILURE;
}

if ((Z_TYPE(retval) == IS_OBJECT) &&
(Z_OBJ(retval) == Z_OBJ_P(val))) {
if (Z_TYPE(retval) == IS_OBJECT && Z_OBJ(retval) == obj) {
/* Handle the case where jsonSerialize does: return $this; by going straight to encode array */
ZEND_GUARD_UNPROTECT_RECURSION(guard, JSON);
return_code = php_json_encode_array(buf, &retval, options, encoder);
Expand All @@ -638,11 +621,9 @@ static zend_result php_json_encode_serializable_object(smart_str *buf, zval *val
}

zval_ptr_dtor(&retval);
zval_ptr_dtor(&fname);

return return_code;
}
/* }}} */

static zend_result php_json_encode_serializable_enum(smart_str *buf, zval *val, int options, php_json_encoder *encoder)
{
Expand Down Expand Up @@ -691,7 +672,7 @@ zend_result php_json_encode_zval(smart_str *buf, zval *val, int options, php_jso

case IS_OBJECT:
if (instanceof_function(Z_OBJCE_P(val), php_json_serializable_ce)) {
return php_json_encode_serializable_object(buf, val, options, encoder);
return php_json_encode_serializable_object(buf, Z_OBJ_P(val), options, encoder);
}
if (Z_OBJCE_P(val)->ce_flags & ZEND_ACC_ENUM) {
return php_json_encode_serializable_enum(buf, val, options, encoder);
Expand Down

0 comments on commit e73e165

Please sign in to comment.