php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #12668 unexpected behavior of preg_replace
Submitted: 2001-08-08 21:06 UTC Modified: 2002-10-16 12:15 UTC
Votes:5
Avg. Score:4.4 ± 0.8
Reproduced:5 of 5 (100.0%)
Same Version:2 (40.0%)
Same OS:0 (0.0%)
From: chuck at 1111-internet dot com Assigned:
Status: Not a bug Package: PCRE related
PHP Version: 4.0.6 OS: FreeBSD 4.0
Private report: No CVE-ID: None
 [2001-08-08 21:06 UTC] chuck at 1111-internet dot com
Simple problem - the script:

<?php
echo preg_replace("/'/e", "\"$0\"", "'");
// that's double-quote, slash, single-quote, slash, e, double-quote
// then double-quote, escaped double-quote, $0, escaped double-quote, double-quote
// then double-quote, single-quote, double-quote
// meaning = "replace all occurrences of single-quote with the same string matched during the search - i.e. single-quote"
?>

should produce one plain single-quote, but instead it produces an escaped single-quote.

No other character seems to exhibit this behavior.

Configuration:
 './configure' '--prefix=/usr/local/php4' '--with-mysql' '--with-apxs=/usr/local/sbin/apxs' '--enable-track-vars' '--with-gd=/usr/local' '--with-zlib-dir=shared' '--with-ttf' '--with-jpeg-dir=/usr/local' '--with-png-dir=/usr/local' '--with-tiff-dir=/usr/local' '--with-mcrypt' '--with-pdflib'

No other unusual configuration setups

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2001-08-09 09:03 UTC] andrei@php.net
This is because preg_replace() runs addslashes() internally on the captured subpatterns before substrituting them into the replacement string. It didn't used to but a few people complained that it was really hard to pass $n to a function because of single and double-quote conflicts. To be frank, I'm not sure how to solve this problem adequately, one group of people want the addslashes() run, the other one doesn't.

 [2001-08-09 09:18 UTC] alindeman@php.net
how about creating either two different functions, or another
attribute to preg_replace, that you can set true/false to run
that add_slashes or not?
 [2001-08-09 09:19 UTC] alindeman@php.net
of course I meant addslashes()
 [2001-08-09 14:07 UTC] chuck at 1111-internet dot com
Ah - I see - so what I'm seeing is actually a symptom of the basic issue that addslashes() is not a perfect reciprocal to putting addslashes-affected characters inside a string - i.e.:

<?php
// double-quoted strings
echo "\""; // produces "
echo "\\"; // produces \
// but
echo "\'"; // produces \'

// single-quoted strings
echo '\''; // produces '
echo '\\'; // produces \
// but
echo '\"'; // produces \"
?>

whereas in mysql:

select "\""; # produces "
select "\\"; # produces \
select "\'"; # produces '

and perl is yet again different (with strings in single-quotes anyway):

print "\""; # produces "
print "\\"; # produces \
print "\'"; # produces '

print '\''; # produces '
print '\\'; # produces \\
print '\"'; # produces "

I suppose backward compatibility would prevent this core behavior from being changed at this stage - it's just kinda screwy that both single-quoting and double-quoting of strings is a bit of a compromise in terms of slashed characters.

Perhaps instead of sending preg_replace carry-forward values through the entire addslashes routine, only " and \ could be returned as slashed, and users could stick with using double-quotes for strings within the (eval'd) replace string... that would prevent people from having to use a hack get it to work as expected.

Thanks,
Chuck

 [2001-08-31 11:12 UTC] andrei@php.net
I could change it so that only " and \ are slashed. From what I remember about some of the complaints before addslashes behavior was implemented, people had security concerns about using some external vars as parts of eval strings. If the vars contained some quotes, some unexpected or dangerous code could be evaluated..
 [2002-02-26 10:39 UTC] michielu at gimo dot dhs dot org
I use the phplib template functions and apparently that library uses the preg_replace routines as well. Whenever I try to put slash-quote data through this template library it gets stipslashes it seems.
The problem boils down to:

preg_replace("/key/", '\' \\\' \\\\\'', "replacekeyvalue");

which should yield:

replace' \' \\'value

but yields

replace' \' \'value

This used to work properly in 4.0.4, but now it seems I have to preparse user input, replace \' and \\ with something else, run preg_replace and repatch the \' and \\ values. This is unworkable!

I'd vote for a configuration variable to fix this. Something in line with magic_quotes_gpc and magic_quotes_sybase. Perhaps magic_quotes_pcre?
 [2002-06-04 15:15 UTC] bernard dot sumption at spc dot ox dot ac dot uk
I have the same problem, but the nature of the material I'm 
working on makes it hard to simply strip offending chars 
from the stings before running preg_replace, which would be 
the easiest solution.

I vote for an additional pcre modifier to turn off magic 
quotes.

Bernie     :o)
 [2002-06-09 01:15 UTC] xuefer at 21cn dot com
before this problem is solved
use preg_replace_callback instead
it's a nice function
:)
 [2002-10-16 12:15 UTC] iliaa@php.net
Thank you for taking the time to write to us, but this is not
a bug. Please double-check the documentation available at
http://www.php.net/manual/ and the instructions on how to report
a bug at http://bugs.php.net/how-to-report.php


 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sun Dec 22 06:01:30 2024 UTC