From: laszlo dot janszky at gmail dot com
Operating system: Windows XP
PHP version: 5.3.1
PHP Bug Type: PCRE related
Bug description: Possible pcre memory leak
Description:
------------
I have a huge recursive regex (about 500bytes), which needs a lot of
memory for backtrace.
The regex matches on templates like
{command1 arg1=$arg1 arg2=$arg2|modifier2
arg3="text"|modifier3:modarg31:modarg32}
etc....
If I use the regex with preg_match_all, then the backtrace memory usage
depends on the count of the commands superexponential.
So:
R^2 = 0,9977 (R^2 for trendline)
ln ln M = 0,0787 * N + 1,9304
[M] = used backtrack memory in bytes
[N] = number of command calls
It don't think that more than 1Mb memory usage is normal for a 0.0002Mb
string.
The recursion memory usage is normal(under 1kb). I'm pretty disappointed
because I can't use my template engine because of a badly written pcre
engine.
Reproduce code:
---------------
$template1='
{display var=$link}
{display var=$link}
{display var=$link}
{display var=$link}
{display var=$link}
{display var=$link}
{display var=$link}
{display var=$link}
{display var=$link}
{display var=$link}
';
$template2='
{display var=$link}
{display var=$link}
{display var=$link}
{display var=$link}
test test test test test
test test test test test
test test test test test
test test test test test
test test test test test
test test test test test
test test test test test
test test test test test
test test test test test
test test test test test
';
$regex='%\\{(?<function>(?:\\w+))(?:(?<list>\\s(?:[\\w_]+(?:\\s[\\w_]+)*\\s)?(?:\\$\\w+(?:->\\w+|\\.\\w+)*|"(?:.*?)"|\\d+(?:\\.\\d+)?)(?:\\|\\w+(?::(?:\\$\\w+(?:->\\w+|\\.\\w+)*|"(?:.*?)"|\\d+(?:\\.\\d+)?))*)*(?:\\s[\\w_]+(?:\\s[\\w_]+)*\\s(?:\\$\\w+(?:->\\w+|\\.\\w+)*|"(?:.*?)"|\\d+(?:\\.\\d+)?)(?:\\|\\w+(?::(?:\\$\\w+(?:->\\w+|\\.\\w+)*|"(?:.*?)"|\\d+(?:\\.\\d+)?))*)*)*(?:\\s[\\w_]+(?:\\s[\\w_]+)*)?)|(?<hash>(?:\\s\\w+=(?:\\$\\w+(?:->\\w+|\\.\\w+)*|"(?:.*?)"|\\d+(?:\\.\\d+)?)(?:\\|\\w+(?::(?:\\$\\w+(?:->\\w+|\\.\\w+)*|"(?:.*?)"|\\d+(?:\\.\\d+)?))*)*)*))(?:\\}(?<block>.*?(?:(?0).*?)*?)\\{/(?P=function))?\\}%usD';
$one_Mb=1024*1024;
$one_kb=1024;
ini_set('pcre.backtrack_limit', $one_Mb);
ini_set('pcre.recursion_limit', $one_kb);
preg_match_all($regex,$template1,$matches1,PREG_SET_ORDER);
preg_match_all($regex,$template2,$matches2,PREG_SET_ORDER);
echo 'test1:<br />';
echo (!count($matches1)?'failed':'ok').'<br />';
echo 'test2:<br />';
echo (!count($matches2)?'failed':'ok').'<br />';
Expected result:
----------------
test1:
ok
test2:
ok
Actual result:
--------------
test1:
failed
test2:
ok
--
Edit bug report at http://bugs.php.net/?id=50264&edit=1
--
Try a snapshot (PHP 5.2):
http://bugs.php.net/fix.php?id=50264&r=trysnapshot52
Try a snapshot (PHP 5.3):
http://bugs.php.net/fix.php?id=50264&r=trysnapshot53
Try a snapshot (PHP 6.0):
http://bugs.php.net/fix.php?id=50264&r=trysnapshot60
Fixed in SVN:
http://bugs.php.net/fix.php?id=50264&r=fixed
Fixed in SVN and need be documented:
http://bugs.php.net/fix.php?id=50264&r=needdocs
Fixed in release:
http://bugs.php.net/fix.php?id=50264&r=alreadyfixed
Need backtrace:
http://bugs.php.net/fix.php?id=50264&r=needtrace
Need Reproduce Script:
http://bugs.php.net/fix.php?id=50264&r=needscript
Try newer version:
http://bugs.php.net/fix.php?id=50264&r=oldversion
Not developer issue:
http://bugs.php.net/fix.php?id=50264&r=support
Expected behavior:
http://bugs.php.net/fix.php?id=50264&r=notwrong
Not enough info:
http://bugs.php.net/fix.php?id=50264&r=notenoughinfo
Submitted twice:
http://bugs.php.net/fix.php?id=50264&r=submittedtwice
register_globals:
http://bugs.php.net/fix.php?id=50264&r=globals
PHP 4 support discontinued: http://bugs.php.net/fix.php?id=50264&r=php4
Daylight Savings: http://bugs.php.net/fix.php?id=50264&r=dst
IIS Stability:
http://bugs.php.net/fix.php?id=50264&r=isapi
Install GNU Sed:
http://bugs.php.net/fix.php?id=50264&r=gnused
Floating point limitations:
http://bugs.php.net/fix.php?id=50264&r=float
No Zend Extensions:
http://bugs.php.net/fix.php?id=50264&r=nozend
MySQL Configuration Error:
http://bugs.php.net/fix.php?id=50264&r=mysqlcfg