Bug #70275 [NEW]: On recursion error, json_encode can eat up all system memory
| From: | royanee at gmail dot com | Date: | Fri, 14 Aug 2015 23:14:26 +0000 |
| Subject: | Bug #70275 [NEW]: On recursion error, json_encode can eat up all system memory | ||
| Groups: | php.bugs | ||
| Request: | Send a blank email to php-bugs+get-195220@lists.php.net to get a copy of this message | ||
From: royanee at gmail dot com
Operating system:
PHP version: 5.6.12
Package: JSON related
Bug Type: Bug
Bug description:On recursion error, json_encode can eat up all system memory
Description:
------------
When json_encode encounters recursion or other errors it will return
false (as long as you are not using the largely undocumented constant
JSON_PARTIAL_OUTPUT_ON_ERROR).
Unfortunately, it waits until after it has processed all of the data to
return the error. This was a problem for me when I was attempting to
export an application state in JSON. As I was using the CLI, it ate up
all of the system memory and at best it would have returned false if I
could have waited an eternity for it to finish.
I've included a test script with a nice handful of circular object
references.
Test script:
---------------
$max_num_objects = 20;
for ($num_objects = 5; $num_objects <= $max_num_objects; $num_objects++)
{
echo PHP_EOL . 'Number of Objects: ' . $num_objects . PHP_EOL;
// Create the objects and link them to each other.
$objects = new stdClass;
for ($i = 0; $i < $num_objects; $i++) {
$objects->$i = new stdClass;
}
for ($i = 0; $i < $num_objects; $i++) {
for ($j = 0; $j < $num_objects; $j++) {
if ($i != $j) {
$objects->$i->$j = $objects->$j;
}
}
}
$starttime = microtime(true);
serialize($objects);
echo '$objects serialize: ' . number_format(microtime(true) -
$starttime, 3) . ' seconds' . PHP_EOL;
$starttime = microtime(true);
if (json_encode($objects) === FALSE) {
echo 'JSON Error #' . json_last_error() . ': ' .
json_last_error_msg() . PHP_EOL;
}
echo '$objects json_encode: ' . number_format(microtime(true) -
$starttime, 3) . ' seconds' . PHP_EOL;
}
Expected result:
----------------
Finishes in less than a second, ideally in a negligible amount of time.
Example:
...
Number of Objects: 10
$objects serialize: 0.000 seconds
JSON Error #6: Recursion detected
$objects json_encode: 0.000 seconds
Actual result:
--------------
...
Number of Objects: 10
$objects serialize: 0.000 seconds
JSON Error #6: Recursion detected
$objects json_encode: 7.227 seconds
--
Edit bug report at https://bugs.php.net/bug.php?id=70275&edit=1
--
Try a snapshot (PHP 5.4): https://bugs.php.net/fix.php?id=70275&r=trysnapshot54
Try a snapshot (PHP 5.5): https://bugs.php.net/fix.php?id=70275&r=trysnapshot55
Try a snapshot (trunk): https://bugs.php.net/fix.php?id=70275&r=trysnapshottrunk
Fixed in SVN: https://bugs.php.net/fix.php?id=70275&r=fixed
Fixed in release: https://bugs.php.net/fix.php?id=70275&r=alreadyfixed
Need backtrace: https://bugs.php.net/fix.php?id=70275&r=needtrace
Need Reproduce Script: https://bugs.php.net/fix.php?id=70275&r=needscript
Try newer version: https://bugs.php.net/fix.php?id=70275&r=oldversion
Not developer issue: https://bugs.php.net/fix.php?id=70275&r=support
Expected behavior: https://bugs.php.net/fix.php?id=70275&r=notwrong
Not enough info: https://bugs.php.net/fix.php?id=70275&r=notenoughinfo
Submitted twice: https://bugs.php.net/fix.php?id=70275&r=submittedtwice
register_globals: https://bugs.php.net/fix.php?id=70275&r=globals
PHP 4 support discontinued: https://bugs.php.net/fix.php?id=70275&r=php4
Daylight Savings: https://bugs.php.net/fix.php?id=70275&r=dst
IIS Stability: https://bugs.php.net/fix.php?id=70275&r=isapi
Install GNU Sed: https://bugs.php.net/fix.php?id=70275&r=gnused
Floating point limitations: https://bugs.php.net/fix.php?id=70275&r=float
No Zend Extensions: https://bugs.php.net/fix.php?id=70275&r=nozend
MySQL Configuration Error: https://bugs.php.net/fix.php?id=70275&r=mysqlcfg