php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #51363 Fatal error raised by var_export() not caught by error handler
Submitted: 2010-03-23 12:58 UTC Modified: 2012-08-06 04:01 UTC
Votes:3
Avg. Score:3.7 ± 0.5
Reproduced:3 of 3 (100.0%)
Same Version:1 (33.3%)
Same OS:1 (33.3%)
From: daan at react dot com Assigned: derick (profile)
Status: Closed Package: Scripting Engine problem
PHP Version: 5.2.13 OS: Debian Etch
Private report: No CVE-ID: None
 [2010-03-23 12:58 UTC] daan at react dot com
Description:
------------
When a fatal error is raised by var_export() when trying to export a resursive array, it is not caught by a user php error handler.

Test script:
---------------
function myErrorHandler($errno, $errstr, $errfile, $errline)
{
    var_dump($errno, $errstr, $errfile, $errline);
    
    /* Don't execute PHP internal error handler */
    return true;
}

set_error_handler("myErrorHandler");

$recursive = array();
$recursive[] = &$recursive; 

var_export($recursive);


Expected result:
----------------
The var_dumped variables

Actual result:
--------------
array ( 0 => array ( 0 => array ( 0 => array ( 0 => array ( 
Fatal error: Nesting level too deep - recursive dependency? in test.php on line x


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2010-03-23 14:16 UTC] derick@php.net
-Status: Open +Status: Assigned -Assigned To: +Assigned To: derick
 [2010-04-22 22:37 UTC] whatrevolution at yahoo dot com
I am curious if the bug OP expects the var_export() output to never end... ever?  I do, because it is a recursive reference, so I'm puzzled that this is considered a bug.

However, perhaps the solution would be to not throw a fatal error, but throw a notice or warning and/or provide some way of telling var_export() how deep to print.

array ( 0 => array ( 0 => array ( 0 => array ( 0 => array (
( ! ) Fatal error: Nesting level too deep - recursive dependency? in /var/www/php_bugs/var_export_recursion_test.php on line 36

Call Stack
#	Time	Memory	Function	Location
1	0.0004	108776	{main}( )	../var_export_recursion_test.php:0
2	0.0004	109968	var_export ( )	../var_export_recursion_test.php:36


PHP Version 5.2.10-2ubuntu6.4

System 	Linux 2.6.31-20-generic x86_64
Build Date 	Jan 6 2010 22:36:47
Server API 	Apache 2.0 Handler 
PHP API 	20041225
PHP Extension 	20060613
Zend Extension 	220060519
Debug Build 	no
Thread Safety 	disabled
Zend Memory Manager 	enabled 

Apache/2.2.12 (Ubuntu)
 [2010-07-02 11:12 UTC] daan at react dot com
No I do not expect it to go on infinitely - the bug is that the php error caused by var_export() in this case is not caught by the error handler, when it should be.
 [2010-11-05 03:32 UTC] yohgaki at ohgaki dot net
I was biten by this bug recently.

Not like php_var_dump() and php_debug_zval_dump(), php_var_export_ex() does not 
have protection against recursive arrays.

Therefore, zend_error() is raised in Zend Engine with E_ERROR. 
(HASH_PROTECT_RECURSION macro in zend_hash.c to be exact) This makes impossible 
to catch exception or error by user error handler.

Possible solutions:
Add recursion protection just like php_var_dump()/php_debug_zval_dump() and 
raize E_NOTICE error for recursive dependency.

Since php_var_export() allows only one zval, export recursive dependency 
correctly by using '&'.


This bug is applicable to 5.2/5.3/trunk.
 [2012-08-06 04:00 UTC] stas@php.net
-Status: Assigned +Status: Closed
 [2012-08-06 04:00 UTC] stas@php.net
This bug has been fixed in SVN.

Snapshots of the sources are packaged every three hours; this change
will be in the next snapshot. You can grab the snapshot at
http://snaps.php.net/.

 For Windows:

http://windows.php.net/snapshots/
 
Thank you for the report, and for helping us make PHP better.


 [2012-08-06 04:00 UTC] stas@php.net
fixed in 5.4 & trunk - var_export no longer produces fatal error but produces 
warning instead on recursion.
 [2012-08-06 04:01 UTC] stas@php.net
Unfortunately, no good way to var_export recursive structures yet. You can use 
serialize() for that.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Nov 21 08:01:29 2024 UTC