Модуль Quote или почему нужно проводить аудит сторонних модулей.

Ко мне обратился один знакомый, который обратил внимание на странное поведение некоторых страниц на его друпал сайте.
При запросе этих страниц, браузер показывал белую страницу.

В логах сервера, при обращении к этим страницам, появлялся мой любимый сиг фолт. Говоря простым языком, модуль php завершался аварийно.

после 5 минут работы в x_debug стало ясно, что виновником всему модуль quote, а точнее функция preg_replace_callback

function _quote_filter_process($text) { if (stristr($text, '[quotе')) {   $text = preg_replace_callback('#\[(quotе.*?)]((?>\[(?!/?quote[^[]*?])|[^[]|(?R))*)\[/quote]#is', '_quote_filter_process_callback', $text); }   return $text; }

Для людей умеющих навскидку читать регулярные выражения сразу становится понятно, что этот regexp занимается тем, что выделяет куски вида [ quote] ….. [/quote] сколь угодно любой вложенности.

Вроде бы все отлично, и можно порадоваться за автора модуля, что он на неплохом уровне владеет регулярными выражениями, но автор модуля, к сожалению для всех его пользователей, не провел тест под сколько нибудь серьезной нагрузкой.

Экспериментальным путем было установлено, что достаточно заключить в [ quote] данные обьемом в 13 килобайт чтобы php завершался аварийно.

Увеличение обьема оперативной памяти, выделяемой для работы скрипта, не решало ровным счетом ничего.

Исправить положение можно заменив строку с регулярным выражением автора модуля на вот это

$regex = '#\[(quote[^\]]*?)\]((?>[^\[]*)(?>(?!\[/?quote[^\]]*?\])\][^\[]*)*)\[/quote\]#is';   while (preg_match($regex, $text))   $text = preg_replace_callback($regex, '_quote_filter_process_callback', $text);

Спасибо -OC-@drupal.org за гениальную подсказку.

Несколько необходимых замечаний.

Использование этого модуля рекомендуется лишь в том случае, если у Вас нет необходимости в конвертации большого обьема разных bb и прочих кодов. И в том случае если Вам действительно необходима вложенность одного кода в другой.

Эффективность использование таких фильтров как quote или bbcode, построенных на регулярных выражениях, обратно пропорционально количеству псевдо-кодов которые они обслуживают.

В настоящий момент рекомендуется использовать алгоритмы построенные на принципах конечных автоматов

Важно
То кто решит использовать код из этого поста, после копипасты поправьте в каждом слове quote последнюю букву. У меня она русская. Сделал я это потому, что не понял как на сайте drupal.ru вставить код содержащий тег quote так, чтобы его местный набор фильтров не преобразовывал

Источник: http://www.drupal.ru/node/34067

© 2009 Обзор CMS