Olcan Teke Olcan Teke - 2 months ago 6
PHP Question

Catastrophic backtracking

i have some problems with my regex:

if (preg_match_all('/{[a-z]+:ce_img:(single|pair)(\s.*)*}/', $files, $matches))
{
echo "ok";
}


For some reason it crashes my site. Ofcourse i already tried to google it and found something about "Catastrophic backtracking" although i'm not sure if this is my problem.

The regex should give me everything between {eggs:ce_img:single(or pair) till the ending }

When i try to change or remove (single|pair) it runs just normally. So it should be something regarding that right?

I'm quite sure that $files isn't the problem.

Does someone know how to solve this?

Regards, Olcan

EDIT:
Here an example of how this regex should work:
image

Answer

Your RegEx crashes your site (due to catastrophic backtracking) because your input file contains at least one of these:

  1. Multiple space characters after target block
  2. A sequence of characters with spaces between after target block. Similar as \s.+.

Solution:

{[a-z]+:ce_img:(?:single|pair)(?:\s+[\w-]+="[^"]*")*\s*}

This specifically matches your pattern. Explanation of last different part:

(?:                    # Start of non-capturing group (a)
    \s+[\w-]+="[^"]*"  # Match similar following string `attr="value"`
)*                     # Many or zero times - end of non-capturing block (a)
\s*                    # Match all space characters if any, before closing brace `}`