'Твердый'? Я так и не нашел надежного синтаксического анализатора BBcode. Все они кажутся разрозненной коллекцией небрежных регулярных выражений, которые легко обмануть, чтобы разрешить атаки с внедрением HTML.
Например, тот, который опубликовал John W, явно может быть использован с несколькими тегами, включая:
[img]xxx" onerror="alert('JS injection!')[/img]
плюс он разрешает javascript:
и другие опасные URL-адреса, не может экранировать &
, запрещает многие символы URL-адреса (включая %
!), В то же время случайно разрешая другие, которые не должны (автор не совсем понял, что там делает экранирование обратной косой черты в строке ), и он не может запретить неправильно вложенные теги или теги, случайно вставленные в атрибуты других тегов... в основном это небезопасный беспорядок, и это нормально для курса парсеров bbcode.
Извините за бесполезный ответ (он был слишком большим, чтобы поместиться в комментарий).
Комментарий ETA: Ну, это не совсем модуль bbcode, просто похожий. Я разделил по строкам, удалил существующие управляющие символы, затем использовал байт 01 в качестве суррогата для &
, 02 для <
и 03 для >
, затем для каждого шага преобразования использовал re.split для (\x02[^\x03]*\x03)
и запускал заменяющее регулярное выражение каждую секунду (не- тег), начиная с «самых внутренних» замен, таких как разрывы строк и эмоции, затем переходя от изображений к ссылкам и разметке курсивом/жирным шрифтом, вставляя \x02html tags\x03
по ходу дела. Затем, наконец, HTML-кодируйте &<>
и замените управляющие коды на &<>
. Это останавливает разметку самой разметки, что является большим источником уязвимостей в упрощенной разметке на основе регулярных выражений.
Если подумать, я также написал настоящий парсер Python bbcode, но только как быстрый хак совместимости; он не предлагает всех возможностей полного bbcode. В частности, он запрещал вложение любого тега диапазона (т. е. тега с закрывающим тегом) внутри любого другого тега диапазона. Это сравнительно легко реализовать, если это приемлемо, поскольку вы можете использовать однопроходное регулярное выражение для сопоставления с любым тегом, а функция замены решает, как заменить на основе имени тега. например.:
\[ (i|b|color|url|somethingelse) \=? ([^]]+)? \] (?: ([^]]*) \[\/\1\] )
(Это регулярное выражение VERBOSE
, поэтому пробелы нужны только для удобочитаемости. Настолько, насколько любое регулярное выражение когда-либо читается.)
Удаление вложенности значительно упрощает количество угловых случаев.
person
bobince
schedule
25.11.2009