php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #20169 implode() clobbers first argument
Submitted: 2002-10-30 05:02 UTC Modified: 2002-10-30 05:45 UTC
From: kims at contrail dot com dot au Assigned: moriyoshi
Status: Closed Package: Reproducible crash
PHP Version: 4CVS-2002-10-30 OS: Debian GNU/Linux (mult ver/arch)
Private report: No CVE-ID:
 [2002-10-30 05:02 UTC] kims at contrail dot com dot au
In general, implode() seems to clobber its first argument in such a way that subsequent accesses can cause a segfault.

I've attached the most trivial example that reproduces the problem (for me). However, the behaviour can differ under different conditions, and I can supply other example if required.

Invariably, implode() will work fine and return a sensible string, but accessing the delimiter variable used will case problems.

In some cases, it's actually possible to print_r() the clobbered delimiter (and see random garbage, but no crash), but it will crash when you concatenate the clobbered string with another string.

Sometimes, php will die somewhat gracefully saying that it can't allocate enough memory, but in my case it was saying that it couldn't allocate 1.5Gb of memory to concatenate strings which were well under 100k combined.

Once, it even set the delimiter string to the string "*RECURSION*".

As a workaround, one can create a string duplicate function that creates a copy that can safely be used, leaving the real delimiter string safe. It works by copying the string one character at a time, as a simple "$copy = $string" will not actually create a new string.

<?
/* return a "duplicate" delimiter string */
function dup ($string)
{
	/* generate a copy of the delimiter string using by
	 * concatenating the individual characters one at a
	 * time.
	 */
	for ($pos = 0; $pos < strlen($string); $pos++)
		$dup .= substr($string, $pos, 1);

	return $dup;
}
?>

<?
	$delimiter = "|";

	echo "delimiter: $delimiter\n";
	implode($delimiter, array("foo", "bar"));
	echo "delimiter: $delimiter\n";
?>

Output was:

Status: 200
Content-type: text/html
X-Powered-By: PHP/4.3.0-dev

delimiter: |
delimiter: Segmentation fault

Backtrace:

#0  0x0811a635 in shutdown_memory_manager (silent=0, clean_cache=0)
    at /home/kims/php4/Zend/zend_alloc.c:461
461					REMOVE_POINTER_FROM_LIST(ptr);
(gdb) bt
#0  0x0811a635 in shutdown_memory_manager (silent=0, clean_cache=0)
    at /home/kims/php4/Zend/zend_alloc.c:461
#1  0x081046d8 in php_request_shutdown (dummy=0x0)
    at /home/kims/php4/main/main.c:920
#2  0x0813cf64 in main (argc=2, argv=0xbffffa84)
    at /home/kims/php4/sapi/cgi/cgi_main.c:1184

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2002-10-30 05:41 UTC] moriyoshi@php.net
Verified with HEAD
 [2002-10-30 05:45 UTC] moriyoshi@php.net
This bug has been fixed in CVS.

In case this was a PHP problem, 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/.
 
In case this was a documentation problem, the fix will show up soon at
http://www.php.net/manual/.

In case this was a PHP.net website problem, the change will show
up on the PHP.net site and on the mirror sites in short time.
 
Thank you for the report, and for helping us make PHP better.


 
PHP Copyright © 2001-2014 The PHP Group
All rights reserved.
Last updated: Wed Apr 23 18:01:55 2014 UTC