PHP preg-match_all calling Apache Segfault

I use two regular expressions to pull jobs from MySQL queries and use them to create an audit trail. One of them is β€œpicky,” which requires quoted column names / etc, and the other does not.

Both of them are tested and correctly parse the values. The problem I'm running into is that with certain picky requests, regexp actually just calls Apache segfault.

I tried various things to determine that this was the reason for exiting the regular expression in the code and just changing the conditional expression to ensure that it was not running (to eliminate some kind of compile-time problem or something else), No questions asked . This only happens when it runs a regex against certain queries that it segfaults, and I cannot find any obvious pattern to tell me why.

The code in question:

if ($picky)
    preg_match_all("/[`'\"]((?:[A-Z]|[a-z]|_|[0-9])+)[`'\"] *= *'((?:[^'\\\\]|\\\\.)*)'/", $sql, $matches);
else
    preg_match_all("/[`'\"]?((?:[A-Z]|[a-z]|_|[0-9])+)[`'\"]? *= *[`'\"]?([^`'\" ,]+)[`'\"]?/", $sql, $matches);

The only difference between them is that the first one removes the question marks in quotes to make them optional and removes the possibility of using different types of quotes by value - only for single quotes. Replacing the first regular expression with the second (for testing purposes) and using the same data eliminates the problem - this is definitely related to the regular expression.

The specific SQL that makes me sad is available at:
http://stackoverflow.pastebin.com/m75c2a2a0

Interestingly, when I delete the selected section, everything works fine. Attempting to send a dedicated partition by itself does not cause errors.

I am very puzzled by what is happening here. Can anyone suggest any suggestions for further debugging or fixing?

EDIT: , Apache (/var/log/apache2/error.log). error.log . .)

[Thu Dec 10 10:08:03 2009] [notice] child pid 20835 exit signal Segmentation fault (11)

, .

EDIT2: Kuroki Kaze, segfault. . 6035 . 6036 segfaults.

EDIT3: pcre.backtrack_limit pcre.recursion_limit php.ini . Apache segfaults, . -, ( 2007 ) PHP/PCRE:
http://bugs.php.net/bug.php?id=40909

EDIT4: , , ( , php.ini ). - . , - .:)

!

+3
3

, , , . SQL- ($sql) name= > $data. , .

            $quoted = '';
            $escaped = false;

            $key = '';
            $value = '';
            $target = 'key';

            for ($i=0; $i<strlen($sql); $i++)
            {
                if ($escaped)
                {
                    $$target .= $sql[$i];
                    $escaped = false;
                }
                else if ($quoted!='')
                {
                    if ($sql[$i]=='\\')
                        $escaped = true;
                    else if ($sql[$i]==$quoted)
                        $quoted = '';
                    else
                        $$target .= $sql[$i];
                }
                else
                {
                    if ($sql[$i]=='\'' || $sql[$i]=='`')
                    {
                        $quoted = $sql[$i];
                        $$target = '';
                    }
                    else if ($sql[$i]=='=')
                        $target = 'value';
                    else if ($sql[$i]==',')
                    {
                        $target = 'key';
                        $data[$key] = $value;
                        $key = '';
                        $value = '';
                    }
                }
            }

            if ($value!='')
                $data[$key] = $value;

!

+1

, , . .

? , ?

EDIT: :

$strings = explode("\n", $sql);

$matches = array(array(), array(), array());

foreach ($strings AS $string) {
    preg_match_all("/[`'\"]?((?:[A-Z]|[a-z]|_|[0-9])+)[`'\"]? *= *[`'\"]?([^`'\" ,]+)[`'\"]?/", $string, $matches_temp);
    $matches[0] = array_merge($matches[0], $matches_temp[0]);
    $matches[1] = array_merge($matches[1], $matches_temp[1]);
    $matches[2] = array_merge($matches[2], $matches_temp[2]);
}
+4

, preg_match, Apache segfault. preg_match, , CMS, (WordPress).

" ", , php.ini:

[Pcre] , PCRE. ; Pcre.backtrack_limit = 100000 pcre.recursion_limit = 200000000 pcre.backtrack_limit = 100000000

( > 200 , 1500 ), , segfaults. .

, ( ) . , , , .

+4

Source: https://habr.com/ru/post/1725302/


All Articles