Недавно я потратил некоторое время на эту проблему.Вот схема моего решения.
Я создал новый класс с именем HtmlSafe, который содержит строки, которые можно безопасно записать в WWW-клиент без уязвимости безопасности.Идея заключалась в том, что функции, которые генерируют теги HTML, возвращают объекты HtmlSafe, а переменные из коробки не являются HtmlSafe.Все, что создает HtmlSafe, также гарантировало безопасность рассматриваемой строки.Конкатенация не-HTML-безопасной строки с HTML-безопасной строкой приводит к экранированию не-HTML-безопасной строки через CGI :: escapeHTML, а затем присоединению к HTML-безопасной строке.Конкатенация другого экземпляра HtmlSafe с HtmlSafe просто объединяет эти строки без экранирования.Я использовал перегрузку, чтобы переопределить.оператор для класса HtmlSafe.
Вооружившись этим, я дал функции $ template-> process () переменную $ output, которая на самом деле была подпрограммой, которая вызывала конкатенацию с HtmlSafe, например:
my $output = HtmlSafe->new("");
$template->process($vars, sub { $output .= $_[0]; });
return $output->unwrap(); # remove HtmlSafe and return underlying string
Мы почти готовы к использованию HtmlSafe TT2.Большим изменением, которое мне пришлось сделать на самом деле, было изменение функции textblock () в Template :: Directive, которая используется Template :: Parser для генерации HtmlSafe экземпляров любого текстового блока, который он пытался выдать.По-видимому, они соответствуют узлам TEXT анализируемого шаблона, поэтому просто выполняем
package MyDirective;
use base "Template::Directive";
sub textblock { my $self = shift; return "$Template::Directive::OUTPUT HtmlSafe->new(" . $self->text(@_) . ")"; }
, который я дал парсеру, вот так:
my $parser = Template::Parser->new({
FACTORY => "MyDirective",
});
В дополнение к этому я определилФильтр none для TT2, который просто оборачивает все, что определено как HtmlSafe, так что вы можете вывести необработанный HTML, если нужно.Это позволяет избежать побега.Фильтр html по умолчанию - no-op, потому что все, что связано с HtmlSafe, теперь все равно экранируется.