#.net #regex #escaping #html-encode #linkify
#.net #регулярное выражение #экранирование #html-кодирование #linkify
Вопрос:
У меня есть строка ввода, которая должна быть удалена из HTML-кодов, поэтому я использую значение по умолчанию.Функция Net .HtmlEncode() для экранирования всех опасных символов.
Теперь я пытаюсь заменить URL-адреса во входной строке на привязки HREF с помощью регулярного выражения.
Проблема в том, что когда я «связываю» URL-адрес перед вызовом.HtmlEncode() теги привязки теряются, что логично. Но когда я делаю linkify ПОСЛЕ вызова.HtmlEncode (), некоторые URL-адреса искажаются, потому что они содержат опасные символы?
Похоже, проблема с куриным яйцом, как ее решить?
Пример:
Строка ввода:
See http://example.com/q=1amp;x=2
Ожидаемый результат:
See <a
href="http://example.com/q=1amp;x=2">http://example.com/q=1amp;amp;x=2</a>
Сначала выполняем HtmlEncode, после чего вызываем Linkify:
See <a
href="http://example.com/q=1amp;amp;x=2">http://example.com/q=1amp;amp;x=2</a>
Сначала делаем Linkify, после чего вызываем HtmlEncode:
See amp;<a
href=amp;quot;http://example.com/q=1amp;amp;x=2amp;quot;amp;>http://example.com/q=1amp;amp;x=2amp;</aamp;>
Решение, которое я использую в настоящее время, заключается в вызове.HtmlDecode() для всех совпадений, найденных регулярным выражением (linkify), но это не на 100% надежно, поскольку допустимый URL-адрес теоретически может содержать шаблон, подобный amp;amp;
которому, который будет декодирован, но не должен.
Комментарии:
1. Возможно, включите простой пример? Неясно, что именно влечет за собой процесс компоновки.
2. Что это за утилита регулярных выражений «linkify»?
3. @JeremyStein Просто регулярное выражение, подобное этому: codinghorror.com/blog/2008/10/the-problem-with-urls.html
4. @Joshua в примере нет части замены. Это прекрасный способ сопоставления, но его недостаточно для замены. Я опубликую ответ…
Ответ №1:
Вы должны по-разному относиться к обычному тексту и ссылкам. Итак, сначала разделите входные данные на части:
If you don't believe me that 1 < 2, see http://example.com/q=1amp;x=2
становится коллекцией с двумя членами:
{ "If you don't believe me that 1 < 2, see ", "http://example.com/q=1amp;x=2" }
Вы кодируете первый и создаете ссылку из второго, кодируя только текст ссылки:
{
"If you don't believe me that 1 amp;< 2, see ",
"<a href="http://example.com/q=1amp;x=2">http://example.com/q=1amp;amp;x=2</a>"
}
Затем вы объединяете результаты в конечный результат.
Но, возможно, было бы лучше, если бы вы использовали библиотеку, созданную для создания HTML. Либо Html Agility Pack, либо ASP.NET , в зависимости от ваших потребностей.
Комментарии:
1. Функция Linkify представляет собой одно регулярное выражение, если я хочу использовать ваш обходной путь, я должен сам написать очень сложную функцию для обнаружения ссылок. И я не создаю HTML, это пользовательский ввод из формы, поэтому я не могу использовать какие-либо библиотеки для создания HTML.
2. Я не понимаю, почему вы не можете использовать библиотеку?
3. Библиотека предназначена для синтаксического анализа ввода html, поэтому я не могу ее использовать, потому что мой ввод представляет собой обычный текст, он не должен содержать HTML. Единственное, что мне нужно сделать, это преобразовать (обычные текстовые) ссылки в html-привязки.
Ответ №2:
Похоже, что атака с использованием межсайтового скриптинга ожидает своего часа.
Большинство подходов, которые я видел, которые преобразуют пользовательский ввод в HTML-разметку, используют для этого какую-то «зарезервированную» пользовательскую последовательность, отличную от HTML, например, ссылка выше на самом деле выглядит так в редакторе переполнения стека:
[Test link to google.][1]
[1]: http://www.google.com
Другие богатые интерфейсы пользовательского интерфейса делают нечто подобное. Это не HTML, но он анализируется и позже выводится как HTML.
Я не уверен, что этот подход будет работать в вашем случае, но это может быть полезным. Обычно вы не хотите давать кому-либо возможность вводить необработанный HTML в ваше приложение, если вы им не доверяете (и поскольку ваш HtmlEncoding часть этого, похоже, что вы им не доверяете).
Комментарии:
1. Я уже разрешаю стили шрифтов и разрывы строк с помощью ubb-кодов, таких как [b] для жирного шрифта и [br] для разрывов, поэтому я мог бы просто добавить [url] в качестве требования к URL-адресам, но это помогло бы только найти URL-адреса в обычном тексте, а не предотвратить HtmlEncode() от того, чтобы все испортить 😉 Я мог бы временно закодировать их с помощью чего-то вроде Base64, выполнить HtmlEncode, а затем откодировать их обратно, но это не похоже на правильное решение.
2. Я читал книгу по Drupal и обнаружил, что существует псевдостандарт того, что я назвал «зарезервированной пользовательской последовательностью, отличной от HTML» — BBCode. Я быстро выполнил поиск .NET BBCode и получил следующее: eksith.wordpress.com/2009/01/14/aspnet-bbcode-c На этой странице также есть ссылка под названием «лучшая альтернатива», которая соответствует решению, которое вы ищете.
Ответ №3:
Вы не можете сделать это с помощью замены регулярных выражений. Вам нужно запустить атрибут href через urlencode, а текст ссылки — через htmlencode.
Комментарии:
1. Мое текущее решение — запустить HtmlEncode() в строке, выполнить RegEx.Replace() и запустить HtmlDecode в HREF. Это работает в 99% случаев, но теоретически существует вероятность того, что действительная ссылка содержит параметры, закодированные в HTML, которые не следует декодировать. Но я никогда раньше не видел такого URL-адреса 😉
2. Я не понимаю, как вы можете писать код для идентификации атрибутов href для вызова HtmlDecode, но вы не можете написать код для идентификации ссылок и их правильной обработки.
3. Возможно, я бы понял, если бы вы показали нам код, который вы используете.