php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #49091 preg_replace bug and potential security issue
Submitted: 2009-07-28 22:36 UTC Modified: 2009-07-29 08:07 UTC
Votes:1
Avg. Score:5.0 ± 0.0
Reproduced:0 of 0 (0.0%)
From: nomail at example dot com Assigned:
Status: Not a bug Package: PCRE related
PHP Version: 5.2.10 OS: Debian Linux 5.0 Lenny
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: nomail at example dot com
New email:
PHP Version: OS:

 

 [2009-07-28 22:36 UTC] nomail at example dot com
Description:
------------
Using the latest stable Debian's PHP 5.2.6-1+lenny3. Can't use anything newer on this production server, sorry.

Note that this malfunction in regular expressions might create exploitable application vulnerabilities (for example, a forum routine to sanitize posts). So this should be treated as a security fix.


// This code works as expected and outputs: ttt www.exa.com/ZZZ ttt 

echo preg_replace( 
	 '#([a-z\.]+)+ZZZ#',
	 'i',
	 'ttt www.exa.com/ZZZ ttt');


// The following code is the same but it will not work, even though it
// should. It will produce just an empty string. The only difference
// between this call and the previous call is that the text contains
// a LONGER domain name (instead of "exa", it contains the word
// "example").

echo preg_replace( 
	 '#([a-z\.]+)+ZZZ#',
	 'i',
	 'ttt www.example.com/ZZZ ttt');


Note: preg_last_error() returns the bogus PREG_SET_ORDER, which should apply only to preg_match_all() and not to preg_replace().

Reproduce code:
---------------
echo preg_replace( 
	 '#([a-z\.]+)+ZZZ#',
	 'i',
	 'ttt www.example.com/ZZZ ttt');

Expected result:
----------------
ttt www.example.com/ZZZ ttt 

Actual result:
--------------
Empty string

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2009-07-28 23:15 UTC] rasmus@php.net
PREG_SET_ORDER is not an error constant.  The actual error is PREG_BACKTRACK_LIMIT_ERROR which is set when the pcre library returns a PCRE_ERROR_MATCHLIMIT

Run the command-line pcre test tool and file a bug with pcre if you think this is a bug.


 [2009-07-28 23:23 UTC] rasmus@php.net
Note also that if you crank up the backtrack limit in pcre, your second example works:

pcre.backtrack_limit=1000000
 [2009-07-29 08:07 UTC] jani@php.net
Not exactly PHP bug..
 
PHP Copyright © 2001-2025 The PHP Group
All rights reserved.
Last updated: Thu Jul 03 13:01:33 2025 UTC