Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,8 @@ PHP NEWS
INT_MIN. (Marc Bennewitz)

- JSON:
. Fixed bug GH-25108 (json_encode() serializes uninitialized properties
with setter hooks as null). (JoaoMarcos44)
. Fixed json_encode() leaving the recursion guard set on objects with hooked
properties after running out of memory while escaping a property name.
(adapik)
Expand Down
4 changes: 4 additions & 0 deletions ext/json/json_encoder.c
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,10 @@ static zend_result php_json_encode_array(smart_str *buf, zval *val, int options,
zval_ptr_dtor(&tmp);
return FAILURE;
}
if (UNEXPECTED(data == &EG(uninitialized_zval))) {
zval_ptr_dtor(&tmp);
continue;
}
}

if (need_comma) {
Expand Down
66 changes: 66 additions & 0 deletions ext/json/tests/gh25108.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
--TEST--
GH-25108 (json_encode() skips uninitialized hooked properties)
--FILE--
<?php

class UninitializedProperties
{
public int $plain;
public int $hooked {
set => $value;
}
public ?int $hookedNullable {
set => $value;
}
}

class MixedProperties
{
public int $firstMissing {
set => $value;
}
public string $first = 'first';
public ?string $middleMissing {
set => $value;
}
public ?string $getterNull {
get => null;
}
public ?string $backedNull = null {
set => $value;
}
public int $backedValue = 42 {
set => $value;
}
public string $last = 'last';
public int $lastMissing {
set => $value;
}
public ?string $virtualSetOnly {
set {}
}
}

$empty = new UninitializedProperties();
echo json_encode($empty), "\n";

$empty->hooked = 7;
$empty->hookedNullable = null;
echo json_encode($empty), "\n";

$mixed = new MixedProperties();
echo json_encode($mixed), "\n";
echo json_encode($mixed, JSON_PRETTY_PRINT), "\n";

?>
--EXPECT--
{}
{"hooked":7,"hookedNullable":null}
{"first":"first","getterNull":null,"backedNull":null,"backedValue":42,"last":"last"}
{
"first": "first",
"getterNull": null,
"backedNull": null,
"backedValue": 42,
"last": "last"
}
Loading