From 4eea3d7c47e8800ec5a34e0b799f38803370bd56 Mon Sep 17 00:00:00 2001 From: Jonathan Druart Date: Wed, 20 Jun 2018 19:38:26 -0300 Subject: [PATCH] AutoEscaping - Koha::Template::AutoEscaping for x in 1 2 3 4 5; do time perl benchmark_AutoEscaping.pl; done perl benchmark_AutoEscaping.pl 0.34s user 0.07s system 96% cpu 0.425 total perl benchmark_AutoEscaping.pl 0.35s user 0.04s system 99% cpu 0.387 total perl benchmark_AutoEscaping.pl 0.35s user 0.04s system 99% cpu 0.396 total perl benchmark_AutoEscaping.pl 0.50s user 0.03s system 99% cpu 0.532 total perl benchmark_AutoEscaping.pl 0.38s user 0.02s system 99% cpu 0.400 total https://bugs.koha-community.org/show_bug.cgi?id=20975 --- C4/Templates.pm | 4 +- Koha/Template/AutoEscaping.pm | 123 ++++++++++++++++++++++++++++++++++++++++++ benchmark_AutoEscaping.pl | 9 ++-- 3 files changed, 130 insertions(+), 6 deletions(-) create mode 100644 Koha/Template/AutoEscaping.pm diff --git a/C4/Templates.pm b/C4/Templates.pm index 806f5dc189..e66abfacdf 100644 --- a/C4/Templates.pm +++ b/C4/Templates.pm @@ -5,7 +5,7 @@ use warnings; use Carp; use CGI qw ( -utf8 ); use List::MoreUtils qw/ any uniq /; -use Template::Stash::AutoEscaping; +use Koha::Template::AutoEscaping; # Copyright 2009 Chris Cormack and The Koha Dev Team # @@ -73,7 +73,7 @@ sub new { COMPILE_DIR => $use_template_cache ? C4::Context->config('template_cache_dir') : '', INCLUDE_PATH => \@includes, FILTERS => {}, - STASH => Template::Stash::AutoEscaping->new, + STASH => Koha::Template::AutoEscaping->new, ENCODING => 'UTF-8', } ) or die Template->error(); diff --git a/Koha/Template/AutoEscaping.pm b/Koha/Template/AutoEscaping.pm new file mode 100644 index 0000000000..ea218116b6 --- /dev/null +++ b/Koha/Template/AutoEscaping.pm @@ -0,0 +1,123 @@ +package Koha::Template::AutoEscaping; + +use Modern::Perl; + +use Template::Config; +use parent ($Template::Config::STASH, 'Class::Data::Inheritable'); + +use Template::Stash::AutoEscaping::RawString; + +our $DEBUG = 0; + +sub new { + my $class = shift; + my $self = $class->SUPER::new(@_); + $self->{method_for_raw} ||= 'raw'; + $self->{method_for_escape} ||= 'escape'; + $self->{_raw_string_class} ||= 'Template::Stash::AutoEscaping::RawString'; + $self->{ignore_escape} ||= []; + $self->{die_on_unescaped} ||= 0; + + foreach my $ops ($Template::Stash::SCALAR_OPS, $Template::Stash::LIST_OPS) + { + $ops->{$self->{method_for_raw}} = sub { + my $scalar = shift; + return $self->{_raw_string_class}->new($scalar); + }; + + $ops->{$self->{method_for_escape}} = sub { + my $scalar = shift; + return $self->{_raw_string_class}->new( + $self->escape($scalar), + ); + }; + + }; + return $self; +} + +sub get_raw_args { + my ( $args, $escaped_class ) = @_; + my $changed = 0; + my @raw_args; + for my $v (@{ $args }) { + my $new_v; + if ( ref $v eq $escaped_class ) { + $changed = 1; + $new_v = $v->[0]; + } elsif (ref $v eq 'ARRAY') { + $new_v = get_raw_args($v, $escaped_class); + if ($new_v) { + $changed = 1; + } else { + $new_v = $v; + } + } else { + $new_v = $v; + } + push @raw_args, $new_v; + } + + return unless $changed; + return \@raw_args; +} + +sub get { + my ( $self, @args ) = @_; + + # note: hack for [% hash.${key} %] [% hash.item(key) %] + # key expected raw string. + if (ref $args[0] eq "ARRAY" && (scalar @{$args[0]} > 2)){ + my $changed = get_raw_args($args[0], 'Koha::Template::AutoEscaping'); + # retry by non-escaped args + if ($changed) { + $args[0] = $changed; + return $self->get(@args); + } + } + + my ($var) = $self->SUPER::get(@args); + if (ref $args[0] eq "ARRAY") { + my $key = $args[0]->[0]; + warn $key if $DEBUG; + if (grep { $key eq $_ } @{ $self->{ignore_escape} }) { + warn "ignore escape $key" if $DEBUG; + return $var; + } + } + + my $ref = ref $var; + # string + if ((!$ref) and (length($var) > 0)) { + return $self->escape($var); + } + # via .raw vmethod + if ($ref eq $self->{_raw_string_class}) { + return "$var"; + } + return $var; +} + +# With %XML => xml_escape subroutine from Mojo +#our %XML = ( +# '&' => '&', +# '<' => '<', +# '>' => '>', +# '"' => '"', +# '\'' => ''' +#); + +sub escape { + my $self = shift; + my $text = shift; + for ($text) { + s/&/&/g; + s//>/g; + s/"/"/g; + s/'/'/g; + } + return $text; +} + +1; diff --git a/benchmark_AutoEscaping.pl b/benchmark_AutoEscaping.pl index d627464777..4eb8eef6e8 100644 --- a/benchmark_AutoEscaping.pl +++ b/benchmark_AutoEscaping.pl @@ -1,11 +1,12 @@ use Modern::Perl; use Template; -use Template::Stash::AutoEscaping; +use Koha::Template::AutoEscaping; + my $tt = Template->new( { ABSOLUTE => 1, PLUGIN_BASE => 'Koha::Template::Plugin', - STASH => Template::Stash::AutoEscaping->new, + STASH => Koha::Template::AutoEscaping->new, } ); @@ -15,7 +16,7 @@ my @loop; for my $i ( 0 .. 10000 ) { push @loop, { foo => '', - bar => 'my bar', + bar => '', }; } my $vars = { @@ -32,7 +33,7 @@ __DATA__ [% pouet %]
[% FOR l IN loop %] - [% l.foo.raw %] [% l.bar.raw %] + [% l.foo %] [% l.bar.raw %]
[% END %]
-- 2.11.0