Michael Peters wrote:
>
> Sam Tregar wrote:
>> On Fri, 14 Apr 2006, Michael Peters wrote:
>>
>>> So by making the "parser smart enough" do you mean copying that huge
>>> regex from H::T and modifying it with the expr regex?
>> Yeah, or using Parse::RecDescent. H::T::E already uses it for
>> expressions, so using it for parsing the template itself might not be
>> much slower.
>
> I'll try my simple approach and see how that works first.
This is a very simple (naive?) approach, so I may have missed something,
but it seems to work.
--
Michael Peters
Developer
Plus Three, LP
--- /home/mpeters/tmp/HTML-Template-Expr-0.06/Expr.pm 2006-03-03 18:07:19.000000000 -0500
+++ Expr.pm.NEW 2006-04-14 14:15:32.000000000 -0400
@@ -147,11 +147,21 @@
my $text = shift;
# find expressions and create parse trees
- my ($ref, $tree, $expr_text, $vars, $which, $out);
- $$text =~ s/<(?:!--\s*)?[Tt][Mm][Pp][Ll]_([Ii][Ff]|[Uu][Nn][Ll][Ee][Ss][Ss]|[Vv][Aa][Rr])\s+[Ee][Xx][Pp][Rr]="(.*?)"\s*(?:--)?>
+ my ($ref, $tree, $before_expr, $expr_text, $after_expr, $vars, $which, $out);
+ $$text =~ s/
+ <(?:!--\s*)?
+ [Tt][Mm][Pp][Ll]_
+ ([Ii][Ff]|[Uu][Nn][Ll][Ee][Ss][Ss]|[Vv][Aa][Rr]) # $1 => which tag
+ (\s+[^<]+)? # $2 => before expr
+ \s+[Ee][Xx][Pp][Rr]=
+ "([^"]*)" # $3 => the actual expr
+ (\s+[^>-]+)? # $4 => after expr
+ \s*(?:--)?>
/
- $which = $1;
- $expr_text = $2;
+ $which = $1;
+ $before_expr = $2 || '';
+ $expr_text = $3;
+ $after_expr = $4 || '';
# add enclosing parens to keep grammar simple
$expr_text = "($expr_text)";
@@ -174,7 +184,7 @@
push(@$expr, $tree);
# add the expression placeholder and replace
- $out . "<\/tmpl_if><tmpl_$which __expr_" . $#{$expr} . "__>";
+ $out . "<\/tmpl_if><tmpl_$which ${before_expr}__expr_" . $#{$expr} . "__$after_expr>";
/xeg;
# stupid emacs - /
use Test::More qw(no_plan);
use HTML::Template::Expr;
my $template = HTML::Template::Expr->new(path => ['t/templates'],
filename => 'extra_attributes.tmpl',
);
$template->param(who => 'me & you',
xss => '<SCRIPT SRC="MALICIOUS.JS" />',
back => 'http://google.com',
js_string => "This is\n'me'",);
my $output = $template->output();
like($output, qr/ME & YOU/);
like($output, qr/<script src="malicious\.js" \/>/);
like($output, qr/Http%3A%2F%2Fgoogle\.com/);
like($output, qr/this is\\n\\'me\\'/);
<tmpl_var expr="uc(who)" escape="HTML">
<tmpl_var escape="HTML" expr="lc(xss)">
<tmpl_var expr="ucfirst(back)" escape="URL">
<tmpl_var expr="lcfirst(js_string)" escape="JS">