php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #69741 preg_replace memory fail
Submitted: 2015-06-01 16:18 UTC Modified: 2015-06-14 04:22 UTC
Votes:1
Avg. Score:4.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:1 (100.0%)
Same OS:1 (100.0%)
From: informatica at ortopediaplus dot com Assigned:
Status: No Feedback Package: PCRE related
PHP Version: 5.6.9 OS: Linux 2.6.32-504.8.1.el6.x86_64
Private report: No CVE-ID: None
 [2015-06-01 16:18 UTC] informatica at ortopediaplus dot com
Description:
------------
Segmentation fault use preg_replace

Test script:
---------------
$pattern = "/<!--TAG_INI-->(.|\n)*?<!--TAG_END-->/";

There are 100000 characters between <!--TAG_INI--> and <!--TAG_END--> in $content


$content = preg_replace($pattern, 'foo', $content);


SEGMENTATION FAULT!!!

Expected result:
----------------
Replace all text between <!--TAG_INI--> and <!--TAG_END--> to 'foo'

Actual result:
--------------
SEGMENTATION FAULT.

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2015-06-01 19:52 UTC] requinix@php.net
-Status: Open +Status: Feedback -Package: *Regular Expressions +Package: PCRE related
 [2015-06-01 19:52 UTC] requinix@php.net
What are your pcre.* INI settings? And are you absolutely sure the string does contain "<!--TAG_END-->"?
 [2015-06-02 08:18 UTC] informatica at ortopediaplus dot com
-Status: Feedback +Status: Open
 [2015-06-02 08:18 UTC] informatica at ortopediaplus dot com
With memory fail hasn't pcre.backtrack_limit and pcre.recursion_limit.

If I use pcre.backtrack_limit or pcre.recursion_limit with any value (1, 100, 1000, 10000), then preg_replace return NULL if match or return $content if not match.

I'm absolutely sure with the string "<!--TAG_END-->".
 [2015-06-04 01:48 UTC] cmb@php.net
See <http://3v4l.org/ICria>. The segfault occurs for PHP 4 and 5,
but has been resolved in current master (the upcoming PHP 7).

However, I wonder why you don't use the following pattern:

  "/<!--TAG_INI-->.*?<!--TAG_END-->/s"
  
That seems to be more intuitive, and works fine even with very old
PHP versions, see <http://3v4l.org/UUFM6>. Apparently, there has
been a bug introduced with PHP 5.2.0 and resolved with PHP 5.3.7,
though.
 [2015-06-04 08:03 UTC] informatica at ortopediaplus dot com
The error persists.

In the documentation, for meta-characters:
.	match any character except newline (by default)

My variable $content has newline (\n).

Fail with \n
"/<!--TAG_INI-->(.|\n)*?<!--TAG_END-->/s"
 [2015-06-04 09:18 UTC] requinix@php.net
-Status: Open +Status: Feedback
 [2015-06-04 09:18 UTC] requinix@php.net
@informatica: . combined with the /s flag is basically the same as what you have now. The big difference is that it doesn't use a capturing group, which will greatly increase performance. Please try what @cmb posted as your problem may just be the result of an inefficient regex.
 [2015-06-14 04:22 UTC] php-bugs at lists dot php dot net
No feedback was provided. The bug is being suspended because
we assume that you are no longer experiencing the problem.
If this is not the case and you are able to provide the
information that was requested earlier, please do so and
change the status of the bug back to "Re-Opened". Thank you.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Dec 21 12:01:31 2024 UTC