php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #28513 preg_match has severe memory leak
Submitted: 2004-05-25 02:11 UTC Modified: 2004-10-23 13:46 UTC
Votes:8
Avg. Score:4.8 ± 0.7
Reproduced:7 of 7 (100.0%)
Same Version:2 (28.6%)
Same OS:4 (57.1%)
From: bens at effortlessis dot com Assigned: hholzgra (profile)
Status: Closed Package: *Regular Expressions
PHP Version: 4.3.6 OS: Fedora Core 1 Linux
Private report: No CVE-ID: None
View Add Comment Developer Edit
Anyone can comment on a bug. Have a simpler test case? Does it work for you on a different platform? Let us know!
Just going to say 'Me too!'? Don't clutter the database with that please !
Your email address:
MUST BE VALID
Solve the problem:
36 + 32 = ?
Subscribe to this entry?

 
 [2004-05-25 02:11 UTC] bens at effortlessis dot com
Description:
------------
I wrote a script to parse a sendmail log file to match records together by message id in order to gather some statistics about a particular relay situation. 

When run, this script quickly swallowed all available RAM, bringing a busy, production system to a standstill.  I reduced the script to the simplest code that causes the memory leak. 

When run as "php -q scriptname.php /var/log/maillog" from the command line, where maillog contains > 500,000 lines, this script will leak memory until the system load average exceeds 5.0. 

Rem out the preg_match on the innermost loop and the memory leak disappears. This bug is found in 4.3.4 and 4.3.6, I haven't tested other versions. 



Reproduce code:
---------------
<?

set_time_limit(0);

// GETS $msgid;
$match="/\]\:\s+([0-9a-zA-Z]+)\:/";

if (!$file=trim($_SERVER['argv'][1]))
        die('You must specify maillog file location');

if ($fp=fopen($file, 'r'))
   {
   while ($line=fgets($fp, 1024))
    if (preg_match($match, $line, $r))
        {
        $msgid=trim($r[1]);
//$mfrom="/$msgid\:\s+from=\<*(.*?)[\s\>].*?relay=.*?\[([0-9\.]+)\]/";
        $mfrom="/$msgid/";

        // REM THIS LINE OUT AND THE MEMORY LEAK STOPS.
        preg_match($mfrom, $line);
        }
   fclose($fp);
   }

?>

Expected result:
----------------
The "top" command should show this PHP instance using < 10% of RAM on a 1 GB RAM system. 

Actual result:
--------------
The "top" command shows > 99% of memory usage on a 1 GB system. 

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2004-08-23 20:52 UTC] R3MOV3CAPSphpbugs at R3MOV3CAPSneodisco dot com
This is a simple, serious, and ugly ugly bug!!!  Took me a while to cut it back, but here is the essence.

<?php
while (1) {
	$body    = "any string";
	$rand    = "different strings".mt_rand(0,mt_getrandmax());
	$pattern = "/$rand/";
	preg_match($pattern, $body, $match);
}
?>

I am using PHP5.0.0 and PHP5.0.01.  These 4 lines chew 50MB per second.  Have a nice day.
 [2004-10-23 13:46 UTC] hholzgra@php.net
Thank you for your bug report. This issue has already been fixed
in the latest released version of PHP, which you can download at 
http://www.php.net/downloads.php

fixed in 4.3.9 and 5.0.2
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri Apr 19 21:01:30 2024 UTC