[Jifty-commit] r2425 - in Template-Declare: lib/Template/Declare t
jifty-commit at lists.jifty.org
jifty-commit at lists.jifty.org
Tue Dec 26 23:16:33 EST 2006
Author: jesse
Date: Tue Dec 26 23:16:33 2006
New Revision: 2425
Added:
Template-Declare/t/xss.t
Modified:
Template-Declare/ (props changed)
Template-Declare/lib/Template/Declare/Tags.pm
Log:
r46503 at pinglin: jesse | 2006-12-26 23:16:22 -0500
* default to escaping user content
Modified: Template-Declare/lib/Template/Declare/Tags.pm
==============================================================================
--- Template-Declare/lib/Template/Declare/Tags.pm (original)
+++ Template-Declare/lib/Template/Declare/Tags.pm Tue Dec 26 23:16:33 2006
@@ -2,10 +2,12 @@
use strict;
package Template::Declare::Tags;
+use Template::Declare;
use vars qw/@EXPORT @EXPORT_OK $PRIVATE $self/;
use base 'Exporter';
+
@EXPORT =
- qw( with template private show get_current_attr attr outs in_isolation $self
+ qw( with template private show get_current_attr attr outs outs_raw in_isolation $self
Tr td ); # these two warns the user to use row/cell instead
our $DEPTH = 0;
@@ -30,10 +32,14 @@
$out;
}
-sub outs {
+sub outs_raw {
$BUFFER .= join( '', grep { defined } @_ );
return '';
}
+sub outs {
+ $BUFFER .= join( '', map { _escape_utf8($_);} grep { defined } @_ );
+ return '';
+}
sub template ($$) {
my $template_name = shift;
@@ -125,12 +131,12 @@
}
sub _tag {
- my $code = shift;
+ my $code = shift;
my $more_code = shift;
- my (
- $package, $filename, $line, $subroutine, $hasargs,
+ my ($package, $filename, $line, $subroutine, $hasargs,
$wantarray, $evaltext, $is_require, $hints, $bitmask
- ) = caller(1);
+ )
+ = caller(1);
# This is the hash of attributes filled in by attr() calls in the code;
@@ -138,9 +144,9 @@
$tag =~ s/^.*\:\://;
my $buf = "\n" . ( " " x $DEPTH ) . "<$tag"
- . join( '',
+ . join( '',
map { qq{ $_="} . ( $ATTRIBUTES{$_} || '' ) . qq{"} }
- sort keys %ATTRIBUTES );
+ sort keys %ATTRIBUTES );
my $had_content = 0;
@@ -157,18 +163,18 @@
my $field = our $AUTOLOAD;
$field =~ s/.*:://;
- $field =~ s/__/:/g; # xml__lang is 'foo' ====> xml:lang="foo"
- $field =~ s/_/-/g; # http_equiv is 'bar' ====> http-equiv="bar"
+ $field =~ s/__/:/g; # xml__lang is 'foo' ====> xml:lang="foo"
+ $field =~ s/_/-/g; # http_equiv is 'bar' ====> http-equiv="bar"
# Squash empty values, but not '0' values
- my $val = join(' ', grep {defined $_ && $_ ne ''} @_);
+ my $val = join( ' ', grep { defined $_ && $_ ne '' } @_ );
- append_attr($field,$val);
+ append_attr( $field, $val );
};
local *append_attr = sub {
- my $field = shift;
- my $val = shift;
+ my $field = shift;
+ my $val = shift;
use bytes;
$val =~ s/&/&/g;
@@ -184,16 +190,15 @@
wantarray ? () : '';
};
+ my $last = join '',map{ ref($_) ? $_ : _escape_utf8($_) } $code->();
- my $last = join '', $code->();
-
- if (length($BUFFER)) {
+ if ( length($BUFFER) ) {
- # We concatenate to force scalarization when $last or $BUFFER is solely a Jifty::Web::Link
+# We concatenate to force scalarization when $last or $BUFFER is solely a Jifty::Web::Link
$buf .= '>' . $BUFFER;
$had_content = 1;
- } elsif (length $last) {
- $buf .= '>'. $last;
+ } elsif ( length $last ) {
+ $buf .= '>' . $last;
$had_content = 1;
} else {
$had_content = 0;
@@ -205,20 +210,22 @@
$BUFFER .= $buf;
$BUFFER .= "\n" . ( " " x $DEPTH ) if ( $buf =~ /\n/ );
$BUFFER .= "</$tag>";
- }
- elsif ($tag =~ m{\A(?: base | meta | link | hr | br | param | img | area | input | col )\z}x) {
+ } elsif ( $tag
+ =~ m{\A(?: base | meta | link | hr | br | param | img | area | input | col )\z}x
+ )
+ {
+
# EMPTY tags can close themselves.
- $BUFFER .= $buf." />";
- }
- else {
+ $BUFFER .= $buf . " />";
+ } else {
+
# Otherwise we supply a closing tag.
- $BUFFER .= $buf."></$tag>";
+ $BUFFER .= $buf . "></$tag>";
}
if ($more_code) {
$more_code->();
- }
- else {
+ } else {
return '';
}
}
@@ -267,4 +274,18 @@
return $buf;
}
+sub _escape_utf8 {
+ my $val =shift;
+ use bytes;
+ no warnings 'uninitialized';
+ $val =~ s/&/&/g;
+ $val =~ s/</</g;
+ $val =~ s/>/>/g;
+ $val =~ s/\(/(/g;
+ $val =~ s/\)/)/g;
+ $val =~ s/"/"/g;
+ $val =~ s/'/'/g;
+ return $val;
+}
+
1;
Added: Template-Declare/t/xss.t
==============================================================================
--- (empty file)
+++ Template-Declare/t/xss.t Tue Dec 26 23:16:33 2006
@@ -0,0 +1,58 @@
+use warnings;
+use strict;
+
+
+package Wifty::UI;
+use base qw/Template::Declare/;
+use Template::Declare::Tags;
+use Test::More tests => 8;
+
+
+template content => sub { div { outs('This is my <b>content</b>') } };
+template content_2 => sub { div { 'This is my <b>content</b>' } };
+template content_3 => sub { div { p{ 'This is my <b>content</b>'}}; };
+template content_4 => sub { div { p{ outs('This is my '); b{ 'content'}}}; };
+
+package Template::Declare::Tags;
+
+use Test::More;
+use HTML::Lint;
+
+our $self;
+local $self = {};
+bless $self, 'Wifty::UI';
+
+Template::Declare->init( roots => ['Wifty::UI']);
+
+
+for (qw(content content_2 content_3 ) ){
+{
+local $Template::Declare::Tags::BUFFER;
+my $simple =(show($_));
+ok($simple =~ 'This is my <b>content');
+ok_lint($simple);
+}
+}
+for (qw(content_4) ){
+{
+local $Template::Declare::Tags::BUFFER;
+my $simple =(show($_));
+ok($simple =~ m/This is my\s*<b>\s*content/);
+ok_lint($simple);
+}
+}
+sub ok_lint {
+ my $html = shift;
+
+ my $lint = HTML::Lint->new;
+
+ $lint->parse($html);
+ is( $lint->errors, 0, "Lint checked clean" );
+ foreach my $error ( $lint->errors ) {
+ diag( $error->as_string );
+ }
+
+}
+
+
+1;
More information about the Jifty-commit
mailing list