php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #39349 Core dump on preg_replace
Submitted: 2006-11-02 21:14 UTC Modified: 2006-12-01 21:37 UTC
Votes:2
Avg. Score:3.5 ± 0.5
Reproduced:2 of 2 (100.0%)
Same Version:2 (100.0%)
Same OS:1 (50.0%)
From: nikolas dot hagelstein at gmail dot com Assigned: andrei (profile)
Status: Not a bug Package: PCRE related
PHP Version: 5.2.0 OS: Netbsd 3.0.1
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: nikolas dot hagelstein at gmail dot com
New email:
PHP Version: OS:

 

 [2006-11-02 21:14 UTC] nikolas dot hagelstein at gmail dot com
Description:
------------
Passing large text to the beyond mentioned regexp makes php core dump

Reproduce code:
---------------
$out=preg_replace("/\{(?:[^{}]|\{(?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})*\})*\}/","",$out);

Where $out is  <content xml:space="preserve">  of http://en.wikipedia.org/w/query.php?what=content&titles=moon

Probably related to some libc issues.




Patches

included-lib-disable-stack-for-recursion (last revision 2013-05-08 20:34 UTC by tsteiner at nerdclub dot net)

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2006-11-03 13:03 UTC] nikolas dot hagelstein at gmail dot com
I was able to narrow down the problem to the following it seems to be size/overflow related:
<?
$out=<<<EOT
{abcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxy
abcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxy
abcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxy
abcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxy
abcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxy
abcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxy
abcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxy
abcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxy
abcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxy
abcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxy
abcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxy
abcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxy
abcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxy
abcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxy
abcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxy
abcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxy
abcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxy
abcdefghijklmnopqrstuvwxyabcdefghijklmnopqr
}
EOT;
$out=preg_replace("/\n/","",$out);
$out=preg_replace("/\{(?:[^{}]|\{(?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})*\})*\}/","",$out);
?>

This Coredumps but if i reduce the string by one char (ie the 'r') it stops coredumping.
 [2006-11-07 14:48 UTC] edink@php.net
You probably run out of stack.

You can try increasing your stack size and trying again on the command line with:

uname -s 16384

for example. If that's what your problem is you can compile an external PCRE that will not use stack but heap (and be slower in the process). You can do that by compiling PCRE using --disable-stack-for-recursion option.

 [2006-11-08 20:44 UTC] nikolas dot hagelstein at gmail dot com
seems to work with ulimit is there any other solution beside recompiling it using the named flag? i mean running out of stack may happen on any system regardless of its default ulimits.
 [2006-11-12 15:15 UTC] nikolas dot hagelstein at gmail dot com
This seems to be stack overflow related in general:
<?php

class Foo {
	function do_something() {
		global $x,$i;		
		$i++;
		echo $i."\n";
		$x->do_something();		
	}
}
$i=0;
$x = new Foo();
$x ->do_something();
?>

Endless recursion results in stack overflow which throws a segmentation fault. Probably libc os related.
 [2006-11-12 19:03 UTC] tony2001@php.net
Yes, endless recursion most likely results in a segfault and this is expected.
 [2006-12-01 20:25 UTC] nlopess@php.net
no bug here. just a stack overflow, which is avoidable by tweaking the new ini options and/or increasing the stack size.
 [2006-12-01 21:37 UTC] nikolas dot hagelstein at gmail dot com
A stack overflow shouldnt cause a segfault.
 [2013-05-08 20:36 UTC] tsteiner at nerdclub dot net
I've uploaded a patch that will disable using the stack for recursion when 
building PCRE with the included library source.  I've found that this completely 
eliminates segfaults when using PCRE functions on long strings.
 [2013-05-08 21:14 UTC] nikic@php.net
@tsteiner: I'm pretty sure that this option was considered, but was found to carry a performance penalty. Would be nice to get some data on this.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri Mar 29 00:01:28 2024 UTC