php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #61579 Segfault preg_replace "/'(\\\\'|\\\\{2}|[^'])*'/" with a long string
Submitted: 2012-03-31 10:53 UTC Modified: 2013-02-17 12:12 UTC
Votes:3
Avg. Score:4.7 ± 0.5
Reproduced:3 of 3 (100.0%)
Same Version:1 (33.3%)
Same OS:1 (33.3%)
From: robin at byte dot nl Assigned:
Status: Wont fix Package: PCRE related
PHP Version: 5.3.10 OS: Debian 2.6.
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: robin at byte dot nl
New email:
PHP Version: OS:

 

 [2012-03-31 10:53 UTC] robin at byte dot nl
Description:
------------
When i use this preg_replace with a long string (3487+ bytes) and single quotes it ends up with a segfault...

$str = preg_replace("/'(\\\\'|\\\\{2}|[^'])*'/", '', $string);

with a string longer than 3487 bytes containing multiple quotes.

results in:

php[26779]: segfault at bf737da8 ip b73e4d43 sp bf737c30 error 6 in libpcre.so.3.12.1[b73d4000+28000]


Test script:
---------------
<?

$sql = "UPDATE proposs_conf SET sku_simple = '0,43588' AND array = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' WHERE sku_conf = 'conf43588';";

var_dump(strlen($sql));
$sql = preg_replace("/'(\\\\'|\\\\{2}|[^'])*'/", '', $sql);
var_dump($sql);
?>


Expected result:
----------------
Remove everything between single quotes.

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

[25236001.222227] php[29917]: segfault at bf37ddc8 ip b744cd43 sp bf37dc50 error 6 in libpcre.so.3.12.1[b743c000+28000]


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2012-03-31 11:18 UTC] robin at byte dot nl
Looked a bit deeper/cleaner:

The preg_replace failes when the string between single quotes is equal or longer than 3399 bytes including quotes... 3487 already did seem like an odd number ;)

cleaner would be if you take $string = "'...3397chars...'";
then it fails with segfault, 

$string = "'...less than 3397 chars...'";  works fine.
 [2012-03-31 18:24 UTC] yohgaki@php.net
Cannot reproduce. Could you download source and test against it?
It seems your system's pcrelib problem.
 [2012-03-31 18:24 UTC] yohgaki@php.net
-Status: Open +Status: Feedback
 [2012-10-08 09:46 UTC] serge dot rivest at gmail dot com
It does appear to be failing on this line:

    foreach ($db->fetchAll($sql) as $a)

Very very likely it's just running out of memory. Although every time it crashes 
we also get this in /var/log/syslog:

Oct  8 20:01:39 dev kernel: [726784.383723] php5-fpm[8644]: segfault at 
7fff6b8a2f00 ip 00007f6607c80a7a sp 00007fff6b8a2e90 error 6 in 
libpcre.so.3.12.1[7f6607c6e000+3c000]

Which is bizarre. Might just be a regexp in the DB driver which is being run when 
the process runs out of memory... Hrm, time to try Serges idea of using xdebug. 
And we see:

    0.8160   12868128                                           -> PDO->quote() 
/www/studyladder.dev222/zendframework/Zend/Db/Adapter/Pdo/Abstract.php:296
    0.8160   12868344                                       -> substr() 
/www/studyladder.dev222/zendframework/Zend/Db/Statement.php:198
    0.8160   12868456                                       -> str_replace() 
/www/studyladder.dev222/zendframework/Zend/Db/Statement.php:199
    0.8160   12868472                                       -> preg_replace() 
/www/studyladder.dev222/zendframework/Zend/Db/Statement.php:204

So, probably not running out of memory. This is the code it's crashing on:

        // get a version of the SQL statement with all quoted                                                         
        // values and delimited identifiers stripped out                                                              
        // remove "foo\"bar"                                                                                          
        $sql = preg_replace("/$q($qe|\\\\{2}|[^$q])*$q/", '', $sql);

Don't really know what it is doing, but the regexp looks like this:

/'(\\'|\\{2}|[^'])*'/

And the query it is crashing on does have a long literal string in it with single 
quotes. Tried changing the query to use a long literal string with double quotes 
and that fixes it. Phew.
 [2012-10-08 10:00 UTC] nikic@php.net
I don't know what exactly the problem is you're facing, but there is a good chance that it's just a stack overflow or similar caused by a very inefficient regex.

You might be able to fix it simply by using "/'(\\\\'|\\\\{2}|[^']+)*'/".

The right approach though would be "/'[^'\\\\]*(?:\\\\.[^'\\\\]*)*'/".
 [2012-10-08 11:24 UTC] serge dot rivest at gmail dot com
I guess that's a question for the people in charge of Zend DB, where this pattern 
originates.

I'm just a user ;)
 [2013-02-17 12:12 UTC] nikic@php.net
-Status: Feedback +Status: Wont fix
 [2013-02-17 12:12 UTC] nikic@php.net
Closing as Wfx as this is a PCRE segfault (which is a known issue we can't really fix).
 
PHP Copyright © 2001-2025 The PHP Group
All rights reserved.
Last updated: Thu Feb 06 19:01:30 2025 UTC