note 73382 added to function.preg-replace
| From: | phpcoder at cyberpimp dot sexventure dot com | Date: | Tue, 20 Feb 2007 22:19:22 +0000 |
| Subject: | note 73382 added to function.preg-replace | ||
| Groups: | php.notes | ||
| Request: | Send a blank email to php-notes+get-123614@lists.php.net to get a copy of this message | ||
preg_replace() is NOT binary-safe.
If a match is made to an ASCII NULL character (0x00) or an ASCII double-quote character (0x22), the
backreference will NOT return those characters! Instead, the backreference contains the 2-character
backslash-escaped sequence \0 or \" respectively.
This causes escaped data to be mixed with unescaped data in the resulting replacement string,
destroying the data integrity.
To use preg_replace() for binary data, you MUST use the "e" modifier in the regular
expression, and then call a function on the backreference to unescape the data in these two special
circumstances.
Since it is only 0x00 and 0x22 that are escaped, you can NOT use stripslashes(). Instead, write
your own function, or use a pair of nested str_replace() function calls.
Here's an example of a URL validator using preg_replace() made binary-safe:
<?php
function url_validate($uncertainURL){
return preg_replace('/([\\x00-\\x20"<>`\\x7F-\\xFF])/e',
"'%'.sprintf('%02X',ord(
str_replace('\\\\0',\"\\0\",
str_replace('\\\\\"','\"','\\1')
)
))",
$uncertainURL);
}
?>
Notice the following:
-A match is made for all ASCII control characters, double-quote, the greater-than and less-than
characters, the grave accent, ASCII DEL, and all 8-bit high characters.
-When an ASCII NULL is matched, the outer str_replace() function call unescapes it.
-When a double-quote is matched, the nested str_replace() function call unescapes it.
-All other matched characters are returned in the back-reference as-is, and therefore do not need
unescaping.
-After unescaping the backreference (if necessary), the sprintf() and ord() functions are called to
replace the instance of the matched character in the source string ($uncertainURL) with a
URL-encoded character code.
The sheer number of backslashes looks a little confusing, but remember, we're 2-levels deep in
escaping context: Literal backslashes have to be doubled in the source code first to make them
literals in the regular expression, and then those have to be doubled again if they are to be
literals in the replacement PHP string expression. So every literal backslash has to be represented
with 4 backslashes!
----
Server IP: 66.207.199.35
Probable Submitter: 64.7.136.101
----
Manual Page -- http://www.php.net/manual/en/function.preg-replace.php
Edit -- https://master.php.net/note/edit/73382
Del: integrated -- https://master.php.net/note/delete/73382/integrated
Del: useless -- https://master.php.net/note/delete/73382/useless
Del: bad code -- https://master.php.net/note/delete/73382/bad+code
Del: spam -- https://master.php.net/note/delete/73382/spam
Del: non-english -- https://master.php.net/note/delete/73382/non-english
Del: in docs -- https://master.php.net/note/delete/73382/in+docs
Del: other reasons-- https://master.php.net/note/delete/73382
Reject -- https://master.php.net/note/reject/73382
Search -- https://master.php.net/manage/user-notes.php