一部のHTMLタグを通すフィルタ
Posted feedbacks - Perl
TripletaiL フレームワークには一部のタグだけを許可する機能があります.
ただ,題意のサンプルのように,属性値を '' で括った場合は
うまく対応できないので,そこを変更しています.
また,閉じタグの自動修復機能が少しバグっていたので
以下のパッチを当てて実行しています.
--- lib/Tripletail/TagCheck.pm 27 Jun 2007 03:01:50 -0000 1.15
+++ lib/Tripletail/TagCheck.pm 31 Aug 2007 01:03:31 -0000
@@ -253,7 +253,9 @@
}
# スタックにプッシュ
- push @$open_stack, $elem;
+ if(!$taginfo->mustBeEmpty) {
+ push @$open_stack, $elem;
+ }
}
}
}
----
実行結果
<<<<
<a href="www.google.com">link</a> <blink>and</blink>
<strong onClick='alert("NG")'>click<br>me!</strong>
>>>>
<a href="www.google.com">link</a> <blink>and</blink>
<strong>click<br>me!</strong>
see: TripletaiL TagCheck のマニュアル
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | #!/usr/bin/perl
use Tripletail qw(/dev/null);
my $input = q{
<a href="www.google.com">link</a> <blink>and</blink>
<strong onClick='alert("NG")'>click<br>me!</strong>
};
my $tc = $TL->newTagCheck;
$tc->setATarget(undef);
$tc->setAllowTag(':BR;A(HREF,NAME);STRONG()');
my $output = $tc->check($input);
print "<<<<\n";
print $input;
print ">>>>\n";
print $output;
|
HTML::Parserで割ときっちりと。 Dan the Perl Monger
see: HTML::Parser
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | #!/usr/local/bin/perl
use strict;
use warnings;
use HTML::Parser;
use HTML::Entities;
sub parse {
my $str = shift;
my @parsed;
my $p = HTML::Parser->new(
start_h => [
sub {
my ( $t, $a, $text ) = @_;
if ($t eq 'a'){
my @a =
map { qq/$_="/ . encode_entities($a->{$_}) . qq/"/ }
grep /^name|href$/, keys %$a;
push @parsed, "<a ".join(" ", @a). ">"
}elsif($t eq 'br' || $t eq 'strong'){
push @parsed, "<$t>"
}else{
push @parsed, encode_entities($text)
}
}, "tagname, attr, text"
],
end_h => [
sub {
my $t = shift;
push @parsed, $t =~ /^a|br|strong$/ ? "</$t>" : "<'/$t>";
}, "tagname"
],
text_h => [
sub {
my $t = shift;
$t =~ s{\n}{</br>}g;
push @parsed, $t;
}, "text"
]
)->parse($str);
join '', @parsed;
}
# for test
local $/;
my $str = <>;
print parse($str);
|
短かさにこだわってみました. < とかは反則ですか?
1 2 3 4 5 6 7 8 | #! /usr/bin/perl
sub E($){ local $_ = shift; s/([&<>"'])/sprintf('&#x%02X;',ord $1)/eg; $_; }
sub T($){ local $_ = shift; no warnings;
s#^<(/?(?:br|strong))\b.*$#<$1>#i ? $_ :
s#^<(/?a\b)[^>]*?(\s?(?:href|name)=(?:'[^']*'|"[^"]*"|[^>\s]*))?
[^>]*?(\s?(?:href|name)=(?:'[^']*'|"[^"]*"|[^>\s]*))?[^>]*?>
#<$1$2$3>#xi ? $_ : E $_; }
$_ = join '', <>; s#(.*?)(</?\w+\b[^>]*>)#E($1).T($2)#eg; print;
|


にしお
#3410()
Rating0/0=0.00
このお題はperezvonさんの提案を元にしています。ありがとうございました。 ただ、いきなりだと難しいかと思ったので、肝の部分以外を先に出題しました。このお題は続編で徐々に難しくなっていきます。
追記:属性に<や>が含まれてしまうケースに漏れのある解答が多いようなのでテストケースを追加します。 これは「この出力なら十分」という意味です。この出力の通りでなければいけないという意味ではありません。 <script foo="<script>alert('bar')</script>">alert('foo')</script> <script foo="<script>alert('bar')</script>">alert('foo')</script> <script foo="<a href='link'>link</a>">alert('foo')</script> <script foo="<a href='link'>link</a>">alert('foo')</script> <a href='www.g>oogle.com'>link</a> <a href="./www.g%3Eoogle.com">link</a>[ reply ]