#48180 [Tbd->Csd]: mb_ereg(i)_replace() evaluate replacement string not escaped properly
| From: | fa@php.net | Date: | Sun, 10 May 2009 21:29:40 +0000 |
| Subject: | #48180 [Tbd->Csd]: mb_ereg(i)_replace() evaluate replacement string not escaped properly | ||
| References: | 1 | Groups: | php.doc.bugs |
| Request: | Send a blank email to doc-bugs+get-2231@lists.php.net to get a copy of this message | ||
ID: 48180
Updated by: fa@php.net
Reported By: 5up3rh3i at gmail dot com
-Status: To be documented
+Status: Closed
Bug Type: Documentation problem
Operating System: *
PHP Version: 5.*CVS, 6CVS (2009-05-08)
-Assigned To:
+Assigned To: fa
New Comment:
This bug has been fixed in the documentation's XML sources. Since the
online and downloadable versions of the documentation need some time
to get updated, we would like to ask you to be a bit patient.
Thank you for the report, and for helping us make our documentation
better.
Previous Comments:
------------------------------------------------------------------------
[2009-05-10 20:11:22] jani@php.net
This has to be documented of course. Using these "eval" parameters is
inherently bad idea..
------------------------------------------------------------------------
[2009-05-09 05:41:04] jani@php.net
Considered and realized that we can't really fix this. You just have to
do the 'addslashes()' yourself. Reason: doing "magical" addslashes()
call on the replacement would cause problems with certain encodings.
------------------------------------------------------------------------
[2009-05-09 05:13:07] jani@php.net
This should show the problem more clearly:
<?php
function test() {echo "THIS SHOULD NOT BE SEEN!!\n";}
function ryat($a) {var_dump($a);}
$str = "', test(), '";
echo "mb_ereg_replace()\n";
var_dump(mb_ereg_replace('^(.*)$', "ryat('\\1')", $str,
'e'));
echo "\npreg_replace()\n";
var_dump(preg_replace('/^(.*)$/e', "ryat('\\1')", $str));
?>
------------------------------------------------------------------------
[2009-05-07 14:54:22] 5up3rh3i at gmail dot com
Description:
------------
when option parameter set e, matches not be escaped.
ex:
<?php
function 80vul() {}
$str = '\', phpinfo(), \'';
mb_ereg_replace('^(.*)$', '80vul(\'\1\')', $str, 'e');
?>
phpinfo() will be evaluated.
mb_ereg_replace()
if ((replace_len - i) >= 2 && fwd == 1 &&
p[0] == '\\' && p[1] >= '0' && p[1] <= '9')
{
n = p[1] - '0';
}
if (n >= 0 && n < regs->num_regs) {
if (regs->beg[n] >= 0 && regs->beg[n] < regs->end[n] &&
regs->end[n] <= string_len) {
smart_str_appendl(pbuf, string + regs->beg[n], regs->end[n] -
regs->beg[n]);
// matches not be escaped
}
preg_replace()
if ('\\' == *walk || '$' == *walk) {
smart_str_appendl(&code, segment, walk - segment);
if (walk_last == '\\') {
code.c[code.len-1] = *walk++;
segment = walk;
walk_last = 0;
continue;
}
segment = walk;
if (preg_get_backref(&walk, &backref)) {
if (backref < count) {
/* Find the corresponding string match and substitute it
in instead of the backref */
match = subject + offsets[backref<<1];
match_len = offsets[(backref<<1)+1] - offsets[backref<<1];
if (match_len) {
esc_match = php_addslashes_ex(match, match_len, &esc_match_len,
0, 1 TSRMLS_CC);
// matches escaped by addslashes()
...
smart_str_appendl(&code, esc_match, esc_match_len);
------------------------------------------------------------------------
--
Edit this bug report at http://bugs.php.net/?id=48180&edit=1