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
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: 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

Add a Patch

Pull Requests

Add a Pull Request

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-2024 The PHP Group
All rights reserved.
Last updated: Thu Mar 28 17:01:29 2024 UTC