php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #47376 Segmentation fault in preg_replace on many repitition of pattern
Submitted: 2009-02-12 22:12 UTC Modified: 2009-02-13 10:55 UTC
Votes:1
Avg. Score:5.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:1 (100.0%)
Same OS:1 (100.0%)
From: pahan at hubbitus dot spb dot su Assigned:
Status: Not a bug Package: PCRE related
PHP Version: 5.3.0beta1 OS: Linux
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: pahan at hubbitus dot spb dot su
New email:
PHP Version: OS:

 

 [2009-02-12 22:12 UTC] pahan at hubbitus dot spb dot su
Description:
------------
On text, where search pattern repeated many times (>643 times by test) php segfaulted (Core dump you may download here: http://ru.bir.ru/_temp/php-pcre-bug/core.8729 ) on preg_replace.

So, if we reduce length of test text ( http://ru.bir.ru/_temp/php-pcre-bug/pcre_bug.text ) on 1 line, or just limit repetition on 1 - it is worked.

All Zend-modules was disabled.

Reproduce code:
---------------
<?
$text = file_get_contents('pcre_bug.text');

echo preg_replace('/(@@ -[\d,]+ \+[\d,]+ @@\s){2,}/s', '-some data-', $text); //Segmentation fault
$text = file();

# Interesting:
#echo preg_replace('/(@@ -[\d,]+ \+[\d,]+ @@\s){2,642}/s', '-some data-', $text); //Work, but result it is not same as needed.
#echo preg_replace('/(@@ -[\d,]+ \+[\d,]+ @@\s){2,643}/s', '-some data-', $text); //PHP Warning:  preg_replace(): Compilation failed: regular expression is too large at offset 33
?>

Expected result:
----------------
Work as when text is less.

Actual result:
--------------
Segmentation fault

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2009-02-12 22:51 UTC] pahan at hubbitus dot spb dot su
Sorry, sorry. Off course line "$text = file();" in reproduce code unnecessary. Please remove it.
 [2009-02-13 00:53 UTC] felipe@php.net
It isn't a PHP bug.

See bug#33468, bug#39387.

Thanks.
 [2009-02-13 09:01 UTC] pahan at hubbitus dot spb dot su
Thank you for the links it was pretty usefully.

I'm read information on it. Very strange read PHP documentation like:
====QUOTE:http://ru.php.net/manual/en/pcre.configuration.php====
pcre.recursion_limit integer 
PCRE's recursion limit. Please note that if you set this value to a *high number you may consume all the available process stack and eventually crash PHP* (due to reaching the stack size limit imposed by the Operating System).
====/QUOTE====
Really you can't provide any runtime check and provide standard way to handle errors (or warnings)???
So, this low level limitation may be in pcre, but crash of PHP is PHP BUG in any case!

And, If you a interesting, I'm make more investigation on this theme:
On default OS limit:
$ ulimit -s
10240
example script behaves as:
//ini_set('pcre.recursion_limit', 9939);//Segmentation fault                                                                   
//ini_set('pcre.recursion_limit', 9938);//Work 

So, If I increase stack size on my system:
$ ulimit -s 65536
all work fine, as expected!!!
 [2009-02-13 10:01 UTC] felipe@php.net
Your pattern could be: /(@@ -[\d,]+ \+[\d,]+ @@\s)(?1)+/
 [2009-02-13 10:10 UTC] felipe@php.net
It's a known PCRE issue, and is documented:
http://www.manpagez.com/man/3/pcrestack/
 [2009-02-13 10:55 UTC] pahan at hubbitus dot spb dot su
>Your pattern could be: /(@@ -[\d,]+ \+[\d,]+ @@\s)(?1)+/
Yes, it seems as workaround (for my current work I apply other workaraund too). It has not similar stack problems?

Wuote from info by you link:
Unfortunately,  the  effect  of  running out of stack is often SIGSEGV,
       though sometimes a more explicit error message is given. You  can  nor-
       mally increase the limit on stack size by code such as this:

         struct rlimit rlim;
         getrlimit(RLIMIT_STACK, &rlim);
         rlim.rlim_cur = 100*1024*1024;
         setrlimit(RLIMIT_STACK, &rlim);

So, main question is - may you correctly handle this problem at all (throw/catch exceptions, fire errors, warnings etc.)?? 
For example, code such:
echo preg_replace('/(@@ -[\d,]+ \+[\d,]+ @@\s){2,643}/s', '-some data-', $text);
generate warning:
PHP Warning:  preg_replace(): Compilation failed: regular expression is too large at offset 33 in /home/pasha/pcre-php-bug/pcre_bug.php on line 14
and all ok - I can correctly handle this situation on my script.

In any case, on production server segmentation fault depended from incoming data is very-very bad idea.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Mon May 06 19:01:32 2024 UTC