Исключения в регэкспах

Serg

Новичок
Исключения в регэкспах

Собственно делал фильтр пользовательской формы. Пользователь кидает текст, нужно вырезать все тэги, кроме разрешенных
пришлось применять preg_replace_callback()
собсно вапрос: нельзяли как-нить обойтись конструкцией preg_replace() ??? - т.е. в одну строку
 

Serg

Новичок
эм... там немножко сложнее
собственно там не удалять надо, а заменять < на &lt;
сорр за непонятку
=========
минимум 3 preg_replace()
или
preg_replace_callback() и внутри callback-a preg_match()...
 

svetasmirnova

маленький монстрик
Serg
Извиняюсь за оффтопик, но меня постоянно мучает этот вопрос: а что хорошего в записи кода в одну строку?
 

Serg

Новичок
htmlspecialchars() и htmlentities() убивают все <
а мне нужно "все кроме"
на данный момент приходится сперва делать htmlspecialchars а потом восстанавливать разрешенное...

2 svetasmirnova:
а код в одну строку - это чисто эстетический интерес :)
 

white phoenix

Новичок
svetasmirnova
зачастую так проще читать
Serg
решение пришедшее мне в голову imho не правильное, т.е. не самое оптимальное, но имеет право на существование. ищешь все _допустимые_ теги и модифицируешь их: "<(/)b>" -> chr(1)."(/)b".chr(1), затем htmlspecialchars, затем обратно chr(1)."(/)b".chr(1) -> "<(/)b>", я думаю chr(1) присылать никто не будет, тем не менее для корректной работы, удали предварительно chr(1) из строки. [offtop]если не удалишь из строки, и будешь использовать рег. выражение для замены chr(1)."(/)b".chr(1) -> "<(/)b>", это может вызвать уязвимость css.[/offtop]
 

Serg

Новичок
Автор оригинала: white phoenix
Serg
решение пришедшее мне в голову imho не правильное, т.е. не самое оптимальное, но имеет право на существование. ищешь все _допустимые_ теги и модифицируешь их: "<(/)b>" -> chr(1)."(/)b".chr(1), затем htmlspecialchars, затем обратно chr(1)."(/)b".chr(1) -> "<(/)b>", я думаю chr(1) присылать никто не будет, тем не менее для корректной работы, удали предварительно chr(1) из строки. [offtop]если не удалишь из строки, и будешь использовать рег. выражение для замены chr(1)."(/)b".chr(1) -> "<(/)b>", это может вызвать уязвимость css.[/offtop]
вот так это выглядит на данный момент
PHP:
$text = preg_replace("/&/is", '&amp;', $text);
$text = preg_replace("/</is", '&lt;', $text);
$text = preg_replace("/&lt;(\/?)(p|div|i|em|b|strong|a|img)([^a-zA-Z0-9])/is", '<\1\2\3', $text);
$text = preg_replace("/&amp;/is", '&\1', $text);
смысл в том, что бы сделать нечто вроде
PHP:
preg_replace("/<([\s\n\!\@\$\#\%\?]*\/?\W*)!(список разрешенных тэгов)(\W*)/is", &lt;\1\2\3, $text);
хм.. правда, у пхп какое-то странное представление об \W и \s
в первое не входят !@#$%&? и т.п.
а во второе вроде бы \r
 

zarus

Хитрожопый макак
а что если...
PHP:
$test_string = "<div>U are very beautiful <b>girl</b>, but alas <img src='/f$k_u_bush' />I've got another <i>business in here</i>. See ya later!</div>";
// Запрещенные парные тэги
$not_allowed_tags['dual'] = array('div','i','emote'....);
// Запрещенные непарные тэги
$not_allowed_tags['single'] = array('img','br','hr'....);
// Строка поиска для парных 
$search_string = '/(?:<((?!'.implode("|",$not_allowed_tags['dual']).'.*?)>)(.*?)(?:<\/(\1)>)/msi';
preg_replace($search_string,'/\2/',$test_string,-1);
Если сменить (?!...) на (?=...) тогда будет требоваться наличие только этих тегов
Это первоначальный вариант, обрезающий тэги, его можно изменить, чтобы он не обрезал их, а только заменял <>
 

zarus

Хитрожопый макак
Даааа, хорошая фишка, но больше похоже на "пальбу из пушки по воробьям". Скачаю себе на будущее, наверняка сгодится. :)
 

zarus

Хитрожопый макак
Я считаю, что при проверке вводимых значений этот пакет целиком лучше применять к полям типа textarea (или как вариант WYSIWYG), так как именно там нужно ослаблять защиту от инъекций. А остальные поля надо жестко подгонять под тот тип, который нужен - intval, floatval и striptags вкупе с удалением всего, что выглядит как <?* ... ?>, < > ... </>, плюс обрезание полей до нужной длины. Ну и не без addslashes (mysql_real_escape_string) и htmlspecialchars.
 

Serg

Новичок
Автор оригинала: zarus
... поля надо жестко подгонять под тот тип, который нужен...
да в принципе это должно быть нормальной практикой
=======
а пир ничо так.. прикольно :)
спасиб
 
Сверху