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">