Subject: | Don't escape HTML meta-characters |
Text::Trac SVN trunk (rev. 370) don't escape HTML meta-characters.
So I wrote a patch to fix this.
In the patch, Mainly I added escape() to InlineNode and BlockNode.
And modified parse() on InlineNode to call escape().
Subject: | text-trac-escape.diff |
Index: t/01-text-trac.t
===================================================================
--- t/01-text-trac.t (revision 418)
+++ t/01-text-trac.t (working copy)
@@ -337,3 +337,37 @@
<p>
[unknown:target label]
</p>
+
+### escape HTML meta-characters
+--- input
+foo <bar> baz.
+foo '''bar''' baz.
+
+ * foo <bar> bar.
+ * foo '''bar''' baz.
+
+ 1. foo <bar> bar.
+ 1. foo '''bar''' baz.
+
+||foo||<bar>||'''baz'''||
+
+{{{
+foo <bar> baz.
+foo '''bar''' baz.
+}}}
+--- expected
+<p>
+foo <bar> baz.
+foo <strong>bar</strong> baz.
+</p>
+<ul><li>foo <bar> bar.</li>
+<li>foo <strong>bar</strong> baz.</li></ul>
+<ol start="1"><li>foo <bar> bar.</li>
+<li>foo <strong>bar</strong> baz.</li></ol>
+<table>
+<tr><td>foo</td><td><bar></td><td><strong>baz</strong></td></tr>
+</table>
+<pre class="wiki">
+foo <bar> baz.
+foo '''bar''' baz.
+</pre>
Index: lib/Text/Trac/Ol.pm
===================================================================
--- lib/Text/Trac/Ol.pm (revision 418)
+++ lib/Text/Trac/Ol.pm (working copy)
@@ -52,7 +52,8 @@
$c->ol({level => $level, space => $space });
- $l =~ s{ $pattern }{<li>$3</li>}xmsg;
+ # parse inline nodes
+ $l =~ s{ $pattern }{'<li>' . $self->replace($3) . '</li>'}xmsge;
if ($c->hasnext and $c->nextline =~ $pattern){
$self->parse($l);
@@ -65,8 +66,6 @@
$c->ol->{space} = 0;
}
- # parse inline nodes
- $l = $self->replace($l);
$c->htmllines($l);
return;
Index: lib/Text/Trac/Ul.pm
===================================================================
--- lib/Text/Trac/Ul.pm (revision 418)
+++ lib/Text/Trac/Ul.pm (working copy)
@@ -33,7 +33,8 @@
$c->ul({ level => $level, space => $space });
- $l =~ s{ $pattern }{<li>$2</li>}xmsg;
+ # parse inline nodes
+ $l =~ s{ $pattern }{'<li>' . $self->replace($2) . '</li>'}xmsge;
if ($c->hasnext and $c->nextline =~ /$pattern/){
$self->parse($l);
@@ -47,7 +48,6 @@
}
# parse inline nodes
- $l = $self->replace($l);
$c->htmllines($l);
return;
Index: lib/Text/Trac/InlineNode.pm
===================================================================
--- lib/Text/Trac/InlineNode.pm (revision 418)
+++ lib/Text/Trac/InlineNode.pm (working copy)
@@ -5,6 +5,7 @@
use Text::Trac::Macro;
use UNIVERSAL::require;
use Text::Trac::LinkResolver;
+use HTML::Entities qw();
tie my %token_table, 'Tie::IxHash';
@@ -94,11 +95,20 @@
}
sub parse {
- my ( $self, $l ) = @_;
- $l =~ s/$self->{rules}/$self->_replace($&, $`, $')/xmseg;
- return $l;
+ my ( $self, $rest ) = @_;
+ my $html = '';
+ while ($rest =~ /$self->{rules}/xms) {
+ $html .= $self->escape($`) . $self->_replace($&, $`, $');
+ $rest = $';
+ }
+ return $html . $self->escape($rest);
}
+sub escape {
+ my ( $self, $s ) = @_;
+ return HTML::Entities::encode($s, '<>&"');
+}
+
sub _replace {
my ( $self, $match, $pre_match, $post_match ) = @_;
if ( $match =~ s/^!// ) {
Index: lib/Text/Trac/Pre.pm
===================================================================
--- lib/Text/Trac/Pre.pm (revision 418)
+++ lib/Text/Trac/Pre.pm (working copy)
@@ -27,7 +27,7 @@
last;
}
else {
- $c->htmllines($l);
+ $c->htmllines($self->escape($l));
}
}
Index: lib/Text/Trac/Table.pm
===================================================================
--- lib/Text/Trac/Table.pm (revision 418)
+++ lib/Text/Trac/Table.pm (working copy)
@@ -21,10 +21,11 @@
while( $c->hasnext and ($c->nextline =~ $pattern ) ){
my $l = $c->shiftline;
$l =~ s{ $self->{pattern} }{$1}xmsg;
- $l = "<tr><td>" . join( "</td><td>", split(/\|\|/, $l) ) . "</td></tr>";
+ $l = "<tr><td>" . join( "</td><td>",
+ map {
+ $self->replace($_) # parse inline nodes
+ } split(/\|\|/, $l) ) . "</td></tr>";
- # parse inline nodes
- $l = $self->replace($l);
$c->htmllines($l);
}
Index: lib/Text/Trac/Heading.pm
===================================================================
--- lib/Text/Trac/Heading.pm (revision 418)
+++ lib/Text/Trac/Heading.pm (working copy)
@@ -15,9 +15,8 @@
my $level = length($1) + $c->min_heading_level -1;
my $id = $self->_strip( $2 );
- $l = qq(<h$level id="$id">$2</h$level>);
+ $l = qq(<h$level id="$id">) . $self->replace($2) . qq(</h$level>);
- $l = $self->replace($l);
$c->htmllines($l);
}
Index: lib/Text/Trac/BlockNode.pm
===================================================================
--- lib/Text/Trac/BlockNode.pm (revision 418)
+++ lib/Text/Trac/BlockNode.pm (working copy)
@@ -54,6 +54,11 @@
}
}
+sub escape {
+ my ( $self, $l ) = @_;
+ return $self->inline_parser->escape($l);
+}
+
sub replace {
my ( $self, $l ) = @_;
return $self->inline_parser->parse($l);