php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #39679 preg_replace with e modifier: design issue
Submitted: 2006-11-29 10:12 UTC Modified: 2006-11-29 11:05 UTC
From: silverbanana at gmx dot de Assigned:
Status: Not a bug Package: PCRE related
PHP Version: 6CVS-2006-11-29 (CVS) OS: Any
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: silverbanana at gmx dot de
New email:
PHP Version: OS:

 

 [2006-11-29 10:12 UTC] silverbanana at gmx dot de
Description:
------------
preg_replace offers the e modifier to evaluate a replacement string as PHP code and use the result of that code for the replacement. This is a very powerful feature. There is, however one problem:

If you want to get the string found by preg_replace things can get complicated, dangerous, even impossible:

This should replace anything between a and b by giving it's strlen.

$search[0]="/a(.*)b/e";
$replace[0]="strlen('\\1')";
$result=preg_replace($search, $replace, $_GET['in']);

Obviously it is possible to do very bad things here, because $_GET['in'] might be a string like: "');dosthbad();$a=('".


Expected result:
----------------
It would be good to have a predefined variable available inside the eval'ed PHP code, that just contains all the values for the parenthesis. Assume this is called $found. Then one could write something like this:

$search[0]="/a(.*)b/e"; // same as before
$replace[0]='strlen($found[1])'; // <- changed
$result=preg_replace($search, $replace, $_GET['in']); // same

And this time things would be safe. Possibly it might be useful to introduce this functionality under a different modifier, but I think it would be a significant improvement for many applications.


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2006-11-29 10:23 UTC] tony2001@php.net
You must filter all the data coming from external sources.
ext/filter is one of the tools you can use for that.
 [2006-11-29 11:05 UTC] silverbanana at gmx dot de
The problem might be, that I cannot filter the string without messing things up or loosing elegance. Ok, maybe using $_GET[something] was a bad example. Just think, that string was read from some file or any other source. Then ext/filter will not be an option, will it? 

One other point: preg_replace is often enough supposed to do filtering in the first place. Now, how much sense does it make to have to filter input to get the filter working.

It's about elegance and speed, not about making things work somehow.
 
PHP Copyright © 2001-2022 The PHP Group
All rights reserved.
Last updated: Mon May 16 16:05:46 2022 UTC