|  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #67467 print_r with $return=true outputs its argument if it is too large
Submitted: 2014-06-18 16:38 UTC Modified: 2017-07-05 08:26 UTC
Avg. Score:4.2 ± 0.8
Reproduced:4 of 4 (100.0%)
Same Version:2 (50.0%)
Same OS:2 (50.0%)
From: igor at wiedler dot ch Assigned:
Status: Open Package: Output Control
PHP Version: 5.5.13 OS:
Private report: No CVE-ID: None
Have you experienced this issue?
Rate the importance of this bug to you:

 [2014-06-18 16:38 UTC] igor at wiedler dot ch
Sufficiently large nested structures will cause print_r to output its first argument, even if the second $return argument is true.

From a glance at how print_r works, it appears to be using output buffering internally. If the output written to the buffer is too large, it will be implicitly flushed.

This is quite a serious problem, as one can easily expose the entire application state accidentally.

This has been reproduced in the FPM and CLI SAPIs.

Test script:
ini_set('memory_limit', '512M');
$a = [];
for ($i = 0; $i < 10000; $i++) {
    $a = [$i, $a];
print_r($a, true);

Expected result:

Actual result:
    [0] => 9999
    [1] => Array
            [0] => 9998
            [1] => Array
                    [0] => 9997
                    [1] => Array



Add a Patch

Pull Requests

Add a Pull Request


AllCommentsChangesGit/SVN commitsRelated reports
 [2014-06-20 08:41 UTC] arjen at react dot com
Duplicate of #66928 and #51362
 [2014-06-20 13:13 UTC]
-Status: Open +Status: Duplicate
 [2015-10-07 09:48 UTC]
-Status: Duplicate +Status: Open
 [2015-10-07 09:48 UTC]
PR for this:

A side-effect of this change would be that if print_r is used in "print" mode and we go out of memory, nothing will be printed (so the reverse of the issue here). I don't know if that's a problem.

Alternatively (or additionally), we could change the OB flushing condition in Probably the `(size_t)PG(memory_limit) < zend_memory_usage(1)` part of the check doesn't do what it's supposed to, as the memory usage will always be lower than the limit (we only *tried* to go higher and failed). We could drop this part. However this would mean we don't flush OB on other fatal errors either. Which may or may not be a problem.
 [2015-10-07 12:07 UTC]
Thinking about it again, we should change the condition to never flush on fatals. This situation is not unique to memory_limit, same could happen with the time limit as well. There's really no reason why a fatal error, which can occur pretty much anywhere, would trigger an OB flush.
 [2017-07-05 08:26 UTC]
This specific issue is fixed as of PHP 7.2, but I still think that we should drop the OB flushing on OOM entirely.
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Feb 24 10:01:27 2024 UTC