по умолчанию экранировать HTML в Template Toolkit - PullRequest
12 голосов
/ 17 декабря 2010

Можно ли как-то настроить Template Toolkit так, чтобы:

[% foo %]

делает то, что вам сейчас нужно сказать:

[% foo | html %]

то есть экранировать HTML в foo? И сделать что-то еще, например:

[% foo | noHtml %]

если я не не хочу сбежать?

Ответы [ 3 ]

5 голосов
/ 19 августа 2011

Наткнулся на ваш вопрос, пытаясь ответить на тот же вопрос для себя.

http://search.cpan.org/~mithaldu/Template-AutoFilter/, кажется, делает то, что мы хотим, но это требует установки другого модуля. Я все равно собираюсь попробовать.

4 голосов
/ 17 декабря 2010

Полагаю, вы могли бы создать свой собственный тайник, расширив Template :: Stash , чтобы он по умолчанию экранировал переменные.

Тем не менее, я думаю, что это не очень хорошая идея. Лучше придерживаться поведения по умолчанию и воздерживаться от пользовательских модификаций, поскольку они, безусловно, сбивают с толку.

1 голос
/ 30 сентября 2016

Недавно я потратил некоторое время на эту проблему.Вот схема моего решения.

Я создал новый класс с именем 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, теперь все равно экранируется.

...