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 &amp; YOU/);
like($output, qr/&lt;script src=&quot;malicious\.js&quot; \/&gt;/);
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">

Reply via email to