Open
Description
Description
The following code:
<?php
function test($i, $s) {
try {
json_decode($s, false, 999999999, JSON_THROW_ON_ERROR);
echo "Test $i passed\n";
} catch (Exception $e) {
echo "Test $i FAILED: $e\n";
}
}
// String like [[[[...1...]]]] fails at length 9999, nesting depth 4999.
test(1, str_repeat('[', 4998) . '1' . str_repeat(']', 4998)); // pass
test(2, str_repeat('[', 4999) . '1' . str_repeat(']', 4999)); // FAIL
// String like [1,[1,[1,...1...]]] fails at length 10001, nesting depth 2499.
test(3, str_repeat('[1,', 2499) . '1' . str_repeat(']', 2499)); // pass
test(4, str_repeat('[1,', 2500) . '1' . str_repeat(']', 2500)); // FAIL
// Flat string like [[1],[1],[1]...] passes even at much greater length.
test(5, '[' . str_repeat('[1],', 9999) . '1]'); // pass
?>
Resulted in this output:
Test 1 passed
Test 2 FAILED: JsonException: Syntax error in json_decode_bug.php:5
Stack trace:
#0 json_decode_bug.php(5): json_decode()
#1 json_decode_bug.php(14): test()
#2 {main}
Test 3 passed
Test 4 FAILED: JsonException: Syntax error in json_decode_bug.php:5
Stack trace:
#0 json_decode_bug.php(5): json_decode()
#1 json_decode_bug.php(18): test()
#2 {main}
Test 5 passed
(I've removed the directory names from the stack trace for brevity.)
But I expected this output instead:
Test 1 passed
Test 2 passed
Test 3 passed
Test 4 passed
Test 5 passed
Note that the exception message ("Syntax error') is different from what I get when I reduce the maximum depth argument from 999999999 to 999. Then I get JsonException: Maximum stack depth exceeded
instead (which is expected).
So it looks like the parser hits an undocumented limit when the input string reaches 10,000 characters, but only for the heavily-nested input.
PHP Version
PHP 8.1.13
Operating System
Arch Linux (x86_64)