Учитывая некоторые многобайтовые наборы символов, могу ли я предположить, что следующее не делает то, что оно предназначалось?
$string = str_replace('"', '\\"', $string);
В частности, если вход был в наборе символов, который может иметь допустимый символ, например, 0xbf5c, так что злоумышленник может ввести 0xbf22, чтобы получить 0xbf5c22, оставив действительный символ, за которым следует некорректная двойная кавычка (").
Есть ли простой способ смягчить эту проблему, или я не понимаю проблему в первую очередь?
(В моем случае строка входит в атрибут value входного тега HTML: echo 'input type = "text" value = "'. $ String. '">';)
EDIT: В этом отношении, как насчет функции, такой как preg_quote ()? Для этого нет аргумента набора символов, поэтому в этом сценарии кажется совершенно бесполезным. Если у вас нет возможности ограничить кодировку UTF-8 (да, это было бы хорошо), похоже, что вы действительно инвалид. Какие функции замены и цитирования доступны в этом случае?
Нет, вы правы: использование однобайтовой строковой функции в многобайтовой строке может привести к неожиданному результату. Вместо этого используйте многобайтовые строковые функции , например mb_ereg_replace
или mb_split
:
$string = mb_ereg_replace('"', '\\"', $string); $string = implode('\\"', mb_split('"', $string));
Редактировать Вот реализация mb_replace
с использованием варианта split-join:
function mb_replace($search, $replace, $subject, &$count=0) { if (!is_array($search) && is_array($replace)) { return false; } if (is_array($subject)) { // call mb_replace for each single string in $subject foreach ($subject as &$string) { $string = &mb_replace($search, $replace, $string, $c); $count += $c; } } elseif (is_array($search)) { if (!is_array($replace)) { foreach ($search as &$string) { $subject = mb_replace($string, $replace, $subject, $c); $count += $c; } } else { $n = max(count($search), count($replace)); while ($n--) { $subject = mb_replace(current($search), current($replace), $subject, $c); $count += $c; next($search); next($replace); } } } else { $parts = mb_split(preg_quote($search), $subject); $count = count($parts)-1; $subject = implode($replace, $parts); } return $subject; }
Что касается комбинации параметров, эта функция должна вести себя как singlebyte str_replace
.
Код совершенно безопасен при использовании правильных многобайтовых кодировок, таких как UTF-8 и EUC-TW, но опасен со сломанными типами, такими как Shift_JIS, GB * и т. Д. Вместо того, чтобы проходить всю головную боль и накладные расходы, чтобы быть в безопасности с этими устаревшими кодировками, я будет рекомендовать только поддержку только UTF-8.
Вы можете использовать mb_ereg_replace
, сначала указав кодировку с помощью mb_regex_encoding()
. Альтернативно, если вы используете UTF-8, вы можете использовать preg_replace
с модификатором u
.
Из того, что я понимаю, большая часть этого типа вставки строк решена с помощью mysql_real_escape_string (); функция.
http://php.net/manual/en/function.mysql-real-escape-string.php