ID: 50264
Comment by: laszlo dot janszky at gmail dot com
Reported By: laszlo dot janszky at gmail dot com
Status: Open
Bug Type: PCRE related
Operating System: Windows XP
PHP Version: 5.3.1
New Comment:
If I remove the recursive part
(?:\\}(?<block>.*?(?:(?0).*?)*?)\\{/(?P=function))?
from the end of the regex, then it works fine...
Previous Comments:
------------------------------------------------------------------------
[2009-11-22 18:47:14] laszlo dot janszky at gmail dot com
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 this bug report at http://bugs.php.net/?id=50264&edit=1