php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #49729 Segfault in PHP 5.3 inside preg_replace
Submitted: 2009-10-01 02:00 UTC Modified: 2009-10-01 17:30 UTC
From: kendallb at amainhobbies dot com Assigned:
Status: Not a bug Package: Reproducible crash
PHP Version: 5.3.0 OS: Mac OS 10.6.1, Win32
Private report: No CVE-ID: None
View Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
If you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: kendallb at amainhobbies dot com
New email:
PHP Version: OS:

 

 [2009-10-01 02:00 UTC] kendallb at amainhobbies dot com
Description:
------------
The following code causes a crash in PHP 5.3.0 (or 5.2.10) as supplied by Zend Studio 7. It also causes a crash in PHP 5.3.0 as compiled by MacPorts, so it appears to be a generic bug. 

Reproduce code:
---------------
<?php
/**
 * Cause a segfault in PHP 5.3.0
 */

$html = "
  THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!
  THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!
  THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!
  THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!
  THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!
  THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!
  THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!
  THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!
  THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!
  THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!
  THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!
  THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!
  THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!
  THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!
  THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!
  THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!
  THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!
  THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!
  THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!
  THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!
  THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!
  THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!
  THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!
  THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!
  THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!
  THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!
  THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!
  THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!
  THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!
  THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!
  THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!
  THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!
  THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!
  THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!
  THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!
  THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!
  THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!
  THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!
  THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!
  THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!
  THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!
  THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!
  THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!
  THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!
  THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!
  THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!   THIS IS A BUNCH OF BULLSHIT!!!
";

$sql = "'" . $html . "'";

$preg = "/'(\\\\'|\\\\{2}|[^'])*'/";

$sql = preg_replace($preg, 'replace', $sql);

echo $sql;


Expected result:
----------------
replace

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

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2009-10-01 10:37 UTC] fa@php.net
Not reproducible on Linux x86, so maybe Mac only.
 [2009-10-01 11:13 UTC] sjoerd@php.net
Could reproduce with PHP 5.3 rev 288893, MacOS X 10.5.8.

(gdb) r
Starting program: /Users/sjoerd/Sources/php-src-5.3/sapi/cli/php -e -f /Volumes/sjoerd-nfs/public_html/svnreps/test/a.php
Reading symbols for shared libraries ++++++++++....... done

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_PROTECTION_FAILURE at address: 0xbf7ffa7c
0x00058fed in match (eptr=0x976eca " OF BULLSHIT!!!\n  THIS"..., ecode=0xaf07ae "_", mstart=0x976404 "'\n  THIS"..., offset_top=4, md=0xbfffeacc, ims=0, eptrb=0x0, flags=0, rdepth=5515) at /Users/sjoerd/Sources/php-src-5.3/ext/pcre/pcrelib/pcre_exec.c:432
432	{
(gdb) bt
....
....
....
#5513 0x0005ad96 in match (eptr=0x976406 "  THIS"..., ecode=0xaf07c3 "V", mstart=0x976404 "'\n  THIS"..., offset_top=4, md=0xbfffeacc, ims=0, eptrb=0x0, flags=0, rdepth=2) at /Users/sjoerd/Sources/php-src-5.3/ext/pcre/pcrelib/pcre_exec.c:1361
#5514 0x00059664 in match (eptr=0x976405 "\n  THIS"..., ecode=0xaf07be "T", mstart=0x976404 "'\n  THIS"..., offset_top=2, md=0xbfffeacc, ims=0, eptrb=0x0, flags=0, rdepth=1) at /Users/sjoerd/Sources/php-src-5.3/ext/pcre/pcrelib/pcre_exec.c:720
#5515 0x0005a87d in match (eptr=0x976405 "\n  THIS"..., ecode=0xaf07ad "g_", mstart=0x976404 "'\n  THIS"..., offset_top=2, md=0xbfffeacc, ims=0, eptrb=0x0, flags=0, rdepth=0) at /Users/sjoerd/Sources/php-src-5.3/ext/pcre/pcrelib/pcre_exec.c:1224
#5516 0x00066e97 in php_pcre_exec (argument_re=0xaf0780, extra_data=0xbfffec3c, subject=0x976404 "'\n  THIS"..., length=6075, start_offset=0, options=0, offsets=0x972530, offsetcount=6) at /Users/sjoerd/Sources/php-src-5.3/ext/pcre/pcrelib/pcre_exec.c:4895
#5517 0x0006d5d6 in php_pcre_replace_impl (pce=0xaf07d0, subject=0x976404 "'\n  THIS"..., subject_len=6075, replace_val=0x972344, is_callable_replace=0, result_len=0xbfffee5c, limit=-1, replace_count=0xbfffee48) at /Users/sjoerd/Sources/php-src-5.3/ext/pcre/php_pcre.c:1040
#5518 0x0006d346 in php_pcre_replace (regex=0x972438 "/'(\\\\'|\\\\{2}|[^'])*'/", regex_len=21, subject=0x976404 "'\n  THIS"..., subject_len=6075, replace_val=0x972344, is_callable_replace=0, result_len=0xbfffee5c, limit=-1, replace_count=0xbfffee48) at /Users/sjoerd/Sources/php-src-5.3/ext/pcre/php_pcre.c:950
#5519 0x0006e347 in php_replace_in_subject (regex=0x9723f8, replace=0x972344, subject=0xc0012c, result_len=0xbfffee5c, limit=-1, is_callable_replace=0, replace_count=0xbfffee48) at /Users/sjoerd/Sources/php-src-5.3/ext/pcre/php_pcre.c:1267
#5520 0x0006eeff in preg_replace_impl (ht=3, return_value=0x9723b8, return_value_ptr=0x0, this_ptr=0x0, return_value_used=1, is_callable_replace=0, is_filter=0) at /Users/sjoerd/Sources/php-src-5.3/ext/pcre/php_pcre.c:1367
#5521 0x0006f00a in zif_preg_replace (ht=3, return_value=0x9723b8, return_value_ptr=0x0, this_ptr=0x0, return_value_used=1) at /Users/sjoerd/Sources/php-src-5.3/ext/pcre/php_pcre.c:1387
#5522 0x0045efd9 in zend_do_fcall_common_helper_SPEC (execute_data=0xc00040) at zend_vm_execute.h:313
#5523 0x004645d9 in ZEND_DO_FCALL_SPEC_CONST_HANDLER (execute_data=0xc00040) at zend_vm_execute.h:1602
#5524 0x0045e112 in execute (op_array=0x9719f0) at zend_vm_execute.h:104
#5525 0x0042ee7e in zend_execute_scripts (type=8, retval=0x0, file_count=3) at /Users/sjoerd/Sources/php-src-5.3/Zend/zend.c:1188
#5526 0x003b3321 in php_execute_script (primary_file=0xbffff7fc) at /Users/sjoerd/Sources/php-src-5.3/main/main.c:2214
#5527 0x00507e5f in main (argc=4, argv=0xbffff8f0) at /Users/sjoerd/Sources/php-src-5.3/sapi/cli/php_cli.c:1190
(gdb) 


 [2009-10-01 16:06 UTC] jani@php.net
See bug #47689
 [2009-10-01 16:49 UTC] kendallb at amainhobbies dot com
Have tested it on Windows and it also fails. We tested on Linux with an older PHP 5.1.x and it succeeded, but we have not tested PHP 5.3.0 on Linux.

This also crashes but should not:

  preg_match('/(.)+/', str_repeat('x', 6000));

Removing the grouping parenthesis causes it not to crash.
 [2009-10-01 16:53 UTC] kendallb at amainhobbies dot com
BTW, bug #47689 is all related to the stack size for the Apache server, but in our case, we are running the standalone PHP binaries, not under apache. 

I can understand that on Windows we may need a much larger stack size for the PHP binary, and on Linux the stack size can grow as large as needed. Is there an easy way to manage the stack size on Mac OS X? I would have thought it would be similar to Linux and allow it to grow as large as necessary?
 [2009-10-01 17:14 UTC] kendallb at amainhobbies dot com
Ok, clearly this is a problem in PCRE since it apparently heavily uses the stack. This makes using preg_replace on larger input data sets pretty much useless unless you are using Linux.

It seems entirely ridiculous to me that processing this:

preg_match('/(.)+/', str_repeat('x', 6000));

can chew up more than 8MB of memory on Mac OS X!? Surely the PCRE developers should have NOT used the stack, and instead used their own efficient heap based stack class?

Either way, this is a serious problem for anyone using PHP, and even more so for anyone using Zend Framework, because the Zend Framework DB adapters all rely heavily on preg_replace to process the input SQL for doing parameter binding. Which pretty much means that unless you are running Linux, you will very, very quickly crash Apache on Windows or Mac OS as soon as you try to submit something to the database that is large in size. Say, a blog post? A HTML product description??

PCRE needs to be fixed IMHO. We are going to find a workaround for preg_replace inside Zend Framework and I am going to submit that workaround for inclusion in future releases, but in reality, we would really all prefer to be using a good version of preg_replace.

BTW, Perl on Mac OS X processes the same regular expressions just fine, so clearly the perl folks know what they are doing :)
 [2009-10-01 17:30 UTC] kendallb at amainhobbies dot com
Well I guess the PCRE folks don't seem to give a shit about this particular bug, so it is not likely to be fixed anytime soon. So much for relying on a useful function like preg_replace on systems other than Linux:

http://bugs.exim.org/show_bug.cgi?id=797
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sun Dec 15 04:01:26 2024 UTC