php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #47020 print_r produces output with $return set to true
Submitted: 2009-01-06 14:05 UTC Modified: 2009-01-15 16:45 UTC
Votes:3
Avg. Score:3.0 ± 0.0
Reproduced:3 of 3 (100.0%)
Same Version:2 (66.7%)
Same OS:0 (0.0%)
From: kulminaator at gmail dot com Assigned:
Status: Not a bug Package: Scripting Engine problem
PHP Version: 5.2.8 OS: Mac OS X 10.5.6
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: kulminaator at gmail dot com
New email:
PHP Version: OS:

 

 [2009-01-06 14:05 UTC] kulminaator at gmail dot com
Description:
------------
print_r creates output although it was not asked to

The code 

$str = print_r($expression, true);  

should never produce any output, but it does if php hits the memory limit closely enough.

My memory_limit is set to 128M (may be this has to be the same to reproduce the bug).

Needless to say, this is a security issue and may output information to clients that never should go there by the code.

Reproduce code:
---------------
<?php
// php.ini has memory limit at  128M
$limit = (str_replace('M','',ini_get('memory_limit')))*1024*1024;
print "Memory limit is $limit bytes\n";
$data = str_repeat('x', $limit / 3 );
$x = print_r($data, true);

Expected result:
----------------
Out of memory error or no output at all.

Actual result:
--------------
The huge amount of x-es (xxxxxxxxxxxx about 40 million times) followed by 

Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 44739243 bytes) in /private/tmp/proof_of_concept.php on line 6

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2009-01-06 15:19 UTC] finsoft at gmail dot com
Same thing reproduced on PHP Version 5.2.6, Windows XP Pro SP3, Apache 2.2.8
 [2009-01-15 15:22 UTC] jani@php.net
This has nothing to do with print_r(). Fix your php.ini not to output errors. 
 [2009-01-15 15:45 UTC] kulminaator at gmail dot com
even with display_errors set to Off or zero, output is still produced
 [2009-01-15 16:45 UTC] kulminaator at gmail dot com
After looking around a bit, this extra output of xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx like data is caused by the weird behaviour of ob_start/ob_end and the fact that output buffers are always flushed when a fatal error is coughed up from below.

straight from the source of ext/standard/basic_functions.c

PHP_FUNCTION(print_r)
{
    zval *var;
    zend_bool i = 0;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|b", &var, &i) == FAILURE) {
        RETURN_FALSE;
    }

    if (i) {
        php_start_ob_buffer (NULL, 0, 1 TSRMLS_CC);
    }

    zend_print_zval_r(var, 0 TSRMLS_CC);

    if (i) {
        php_ob_get_buffer (return_value TSRMLS_CC);
        php_end_ob_buffer (0, 0 TSRMLS_CC);
    } else {
        RETURN_TRUE;
    }
}


Here the zend_print_zval_r causes creating/appending to ob , ob hits the memory limit and bang, the output is created, although it never should be.

Can we hope for a fix (either root out the issue of ob being flushed or avoiding ob in the first place ?) or are supposed to remove all sensitive data from ever reaching print_r ?
 [2010-06-30 13:53 UTC] cxscott at uk dot insight dot com
I can confirm that this is definitely an issue, even with error reporting set to off. I'm using PHP 5.3.2 running on 64-bit Red Hat Linux.
 [2010-10-22 12:52 UTC] spaze-bugs at exploited dot cz
The same issue was present in var_export() though that's now fixed in 5.3.3:
"Rewrote var_export() to use smart_str rather than output buffering, prevents data disclosure if a fatal error occurs (CVE-2010-2531). (Scott)"
 
PHP Copyright © 2001-2025 The PHP Group
All rights reserved.
Last updated: Sat Jul 05 15:01:34 2025 UTC