Bug #70275 [Opn->Asn]: On recursion error, json_encode can eat up all system memory

From: Date: Mon, 09 Nov 2015 19:28:30 +0000
Subject: Bug #70275 [Opn->Asn]: On recursion error, json_encode can eat up all system memory
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-197137@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=70275&edit=1 ID: 70275 Updated by: bukka@php.net Reported by: royanee at gmail dot com Summary: On recursion error, json_encode can eat up all system memory -Status: Open +Status: Assigned Type: Bug Package: JSON related PHP Version: 5.6.12 -Assigned To: +Assigned To: bukka Block user comment: N Private report: N Previous Comments: ------------------------------------------------------------------------ [2015-08-14 23:14:23] royanee at gmail dot com 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 this bug report at https://bugs.php.net/bug.php?id=70275&edit=1

« previous php.bugs (#197137) next »