ID:               30698
 Updated by:       [EMAIL PROTECTED]
 Reported By:      php at richardneill dot org
 Status:           Bogus
 Bug Type:         Documentation problem
 Operating System: Linux
 PHP Version:      4.3.9
 New Comment:

Unescaped quotes doesn't cause parse error thanks to escaping provided
by /e.

<?php
echo preg_replace('~.*~e', '"\\0"', '"'); // ", no parse error
?>

I'm against messing this part with magic_qutes and SQL injection
issues.


Previous Comments:
------------------------------------------------------------------------

[2005-04-05 16:47:43] php at richardneill dot org

I don't think this is exactly bogus, since I think the documentation is
not clear. The documentation for /e says just:

--------------------
 If this modifier is set, preg_replace()  does normal substitution of
backreferences in the replacement string, evaluates it as PHP code, and
uses the result for replacing the search string. Single and double
quotes are escaped by backslashes in substituted backreferences.
----------------------

Given that this is a really awkward potential gotcha, especially when
it interacts with PHP's magic quotes and SQL, I think it is worth
stressing that: 

a)If the backreference is single quoted, eg:
   ('\\1')
then 
   i)Double quotes will become escaped by \
   ii)Unescaped single quotes will cause a parse error.

b)If the backreference is double quoted, eg:
   ("\\1")
then 
   i)single quotes will become escaped by \
   ii)Unescaped double quotes will cause a parse error.

c)If the source is user-input which has had magic-quotes applied, then

  quotes of type (i) will end up doubly escaped causing an SQL error,
and one of the escapes must be removed
  quotes of type (ii) will lose their magic quoting, and need to have
the escape restored.

------------------------------------------------------------------------

[2005-04-05 15:46:35] [EMAIL PROTECTED]

It works as expected and documented:

modify('\\1') is translated to modify('single quote \', a double quote
\", and a backslash\\') resulting in

single quote ', a double quote \", and a backslash\

---

modify("\\1") is translated to modify("single quote \', a double quote
\", and a backslash\\") resulting in

single quote \', a double quote ", and a backslash\



------------------------------------------------------------------------

[2004-11-11 01:44:09] php at richardneill dot org

I hope this test case is more useful. 

<?
$message="This string contains a single quote ', a double quote \", and
a backslash\ .";

function modify($string){
        return "START $string END";
}

$new_bad=preg_replace("/^(.*)$/e", "'BEGINNING '.modify('\\1').'
FINISH'",  $message);
$new_good=preg_replace("/^(.*)$/e", "'BEGINNING '.modify(\"\\1\").'
FINISH'",  $message);

echo "MESSAGE:\n$message\n\n";
echo "NEW_BAD:\n$new_bad\n\n";
echo "NEW_GOOD:\n$new_good\n\n";
echo "NB: none of these are the same!\n"


/*
The problem is that depending on precisely how the replacements in the
preg_replace are quoted,
the escaping is different. This is not documented. $new_bad and
$new_good should be the same!

Furthermore, in the case where $message is user-submitted, and has
arrived via magic_quotes, ready for
insertion into a database, modify() will want to include a
strip_slashes, to remove the redundant slashes (but leaving the
original ones). The above behaviour could leave a database vulnerable
to sql injection attacks

My personal favoured solution would be for the /e modifier not to add
the extra backslashes.
*/
?>

------------------------------------------------------------------------

[2004-11-10 18:24:12] [EMAIL PROTECTED]

Thank you for this bug report. To properly diagnose the problem, we
need a short but complete example script to be able to reproduce
this bug ourselves. 

A proper reproducing script starts with <?php and ends with ?>,
is max. 10-20 lines long and does not require any external 
resources such as databases, etc.

If possible, make the script source available online and provide
an URL to it here. Try avoid embedding huge scripts into the report.

Btw, the example from docs works just fine for me.

------------------------------------------------------------------------

[2004-11-06 08:17:25] php at richardneill dot org

Description:
------------
The documentation for preg_replace states that /e  
will cause it to add extra slashes to single and double 
quotes. 
 
This means that, if one has magic_quotes on, one must 
filter out the spurious new backslashes, using something 
like:  
$block=str_replace(array('\\\\\'','\\\\"'),array('\\\'','\\"'),
$block);  
 
However, in fact, it appears that preg_replace is adding 
the backslashes to double quotes, but NOT to single 
quotes. 
 
There's also a useful comment here: 
http://uk2.php.net/manual/en/function.preg-replace.php 
steven -a-t- acko dot net  08-Feb-2004 05:45  

Reproduce code:
---------------
FAILS:

$message=preg_replace("/((?<=(\n))|(?<=^))( *>(.*))(\n\n|$)/seU", 
"'$quote_font_start BEGIN'.fixblock('\\3',$quote).' END
$quote_font_end\n\n'",  $message);

WORKS:
                        $message=preg_replace("/((?<=(\n))|(?<=^))( 
*>(.*))(\n\n|$)/seU", 
"'$quote_font_start BEGIN'.fixblock(\"\\3\",$quote).' END
$quote_font_end\n\n'",  $message);

Expected result:
----------------
I'm not sure whether this is simply a documentation bug, 
but it's very weird behaviour! It is also a nasty one, 
because it can leave the database vulnerable. Thanks for 
your help. 



------------------------------------------------------------------------


-- 
Edit this bug report at http://bugs.php.net/?id=30698&edit=1

Reply via email to