Вставка кода в комментариях
C самого начала работы этого блога я предусмотрел возможность вставлять в записи и комментарии код с помощью плагина WP-Syntax. Даже специально перед формой добавления комментария написал подсказку, как правильно использовать синтаксис вставки кода. Именно поэтому меня страшно раздражало, когда посетители вставляли код так, что половина его съедалась и я не мог понять о чем идет речь и как помочь комментирующему. Продолжалось это ровно до того момента, пока я не попытался сам ответить с кодом в комментарии, будучи не авторизован в блоге. К моему большому удивлению часть моего кода в комментарии оказалась испорченной. Как пример: вот из такого простого кода в комментарии:
Я получил почему-то обрезок в виде:
Все div'ы оказались вырезанными из комментария, даже несмотря на то, что их защищали теги pre (с тегами code тоже самое, кстати).
Я стал разбираться в ситуации и довольно быстро нашел проблему. Оказывается, что нефильтрованный HTML-код разрешено вставлять в блоге только его администратору. Естественно, что давать возможность вставки любого HTML-кода обычным посетителям очень плохая идея, но меня убило, что код нельзя вставлять даже в специальных тегах code, которые, собственно, и предназначены именно для вставки кода. WordPress'у по барабану вставлен код в тегах code или нет, он все равно фильтрует весь комментарий. Причем, что интересно – сами теги code он не фильтрует, не считая их опасными, но вот их содержимое зачем-то портит, хотя чем оно может навредить блогу, находясь в ограничивающих тегах?
Анализ кода движка показал, что WordPress фильтрует HTML-теги в момент добавления комментария, а поэтому дело свелось к следующему: не дать WordPress'у удалить HTML-код, заключенный в теги code. Это уже оказалось задачей достаточно простой – надо заставить WordPress не воспринимать HTML-код, как код. А для этого надо всего лишь заменить все атрибуты тегов в виде < и > на их escape-последовательности < и >. Не буду вас дальше утомлять: вот готовый хак для тегов code и pre, его достаточно добавить в файл functions.php вашего шаблона:
function replace_code_pre ($matches){ $out = str_replace( array('<','>'), array('<','>'), $matches[3] ); return "<{$matches[1]}{$matches[2]}>".$out."</{$MATCHES[1]}>"; } function code_in_comments($comment_text){ $comment_text = preg_replace_callback ('!<(pre|code)([^>]*)>(.*?)</\\1>!ims', 'replace_code_pre', $comment_text); return $comment_text; } add_filter ('pre_comment_content','code_in_comments'); |
Теперь при добавлении комментария:
Вы увидите именно код, а не обрезок:
Для плагина WP-Syntax и его тегов pre аналогично - из комментария:
можно получить на этот раз правильный код:
Причем остальная часть комментария данными фильтрами не трогается и весь HTML-код вне тегов code или pre будет удален, если автор комментария не имеет прав добавления нефильтрованного HTML-кода в блоге. Надеюсь, данный способ кому-нибудь пригодится.
PS. Огромное спасибо Тимуру Камаеву, автору сайта
Понравился пост? Подпишись на обновления по RSS или Twitter !
#1,
Этот код не совершенен, он обратные слэши будет вырезать из кода. И на форуме гдет читал про глюки в модификатором e для preg_replace. И зачем нужна проверка current_user_can - для всех пользвателей нужно менять < и >
Когда у себя на блоге эту проблему решал, написал такой хак для этого, пашет на ура.
у меня тут(в коде) еще такой же фильтр для контента прицеплен: content_save_pre
Хотел у себя решение этой пробелмы написать, да чет забыл совсем про эту статью.
#2,
да, все проверил и действительно код содержал ошибки. поправил статью с учетом вашего правильного кода, еще раз спасибо ))
#3,
А почему бы не использовать для этого привычный многим и более функциональный плагин SyntaxHighlighter?
#4,
потому что он на мой взгляд совершенно убог. да и речь в статье не о плагинах вставки кода, а о поведении самого вордпресса.
#5,
А этот чем не убог?
придобавлении в комменты кода он мне всю страницу разорвал,может еще что добавить нужно, а то я просто вывод синтаксиса в кнопке сменила, размер выставила 90% и даже правило css не помогло
и как насчет вот этого?
http://zaan.ru/wordpress-uyazvimost-v-plagine-wp-syntax/
#6,
вам там любой текст без пробелов разорвет страницу. надо жестко в css прописывать размеры дива, где выводятся комментарии, тогда появится полоса прокрутки.
гон. данная уязвимость существовала до версии 0.9.1 - сейчас банально эксплойты не работают, лично проверял.
#7,
при вставленном для текстового поля правиле
текст не рвет страницу а переновит символы автоматом на следующюю строчку кроме кода
свойство кроссбраузерно. Проверено
#8,
и тем не менее, задавать блок вывода комментариев надо жестко, указав его ширину в пикселях. тогда код не будет вам портить вывод комментов.
#9,
Добавил код, теперь не теги не удаляются но и подсветка кода не появляется, wp-syntax тег не обрабатывает, не добавляет
и остальное в комментарий.
#10,
не в курсе. а как полностью выглядит такой код в комменте?
#11,
доброго дня. поставил недавно вордпресс последней версии 5.3. Проверил в комментариях и для админа и для пользователя обрезаются все Html коды.
У меня вопрос подойдет ли данный код для решения проблемы с обрезанием Html именно в версии 5.3?????
Не надо ли менять код для версии 5.3, и не создаст ли код какую либо уязвимость????
Благодарю за ответы на вопросы. С ув. Антон.
#12,
а добавить код и проверить вы не можете?
#13,
Я если чесно не селен в wordpress. Боюсь добавлю что то сломается поэтому хотелось услышать ваше мнение как автора кода перед добавлениемю Может вы тестировали на 5.3???? И вопрос не создаст ли код уязвимостей тоже беспокоюсь. Ответьте пожалуйста как есть буду очень признателен. Спасибо.
#14,
нет, не тестировал. 5.3 еще не устанавливал.
но не вижу причин, чтобы этот код не работал на 5.3 - в комментариях давно ничего в движке не менялось.
#15,
Е второй мой вопрос основное мое беспокойство не создаст ли код уязвимойстей.??? Спасибо благодарю за ответы может быть на мои глупые вопросы.
#16,
нет, не создаст.
#17,
Спасибо еще раз за ответ. И такой вопрос может на пятой линейки тестировали код????
#18,
этот сайт работает на 5.2 и этот код на нем установлен - все работает.
#19,
Спасибо. За ответы. Тогда смело ставлю.
С Ув. Антон.