#!/usr/bin/perl -w package MT::Plugin::SafeHref; our $VERSION = 0.1; use strict; use HTML::Parser; use HTML::Entities; use lib '../lib'; use MT::Template::Context; use vars qw( $p $output ); MT::Template::Context->add_global_filter(safe_urls => \&fix_links); MT::Template::Context->add_global_filter(safe_url => \&encode_url); #---------------------------------------------------------------------------- my @url_attrs = qw( a href area href link href img src img longdesc img usemap object classid object codebase object data object usemap q cite blockquote cite ins cite del cite form action input src input usemap head profile base href script src frame src frame longdesc iframe src iframe longdesc applet codebase ); my %url_tags = (); while (@url_attrs) { $url_tags{shift(@url_attrs)}{shift(@url_attrs)}=1; } #---------------------------------------------------------------------------- sub fix_links { my $input = shift; $p ||= HTML::Parser->new( api_version => 3, start_h => [ \&tag_start, "tagname,tokenpos,text" ], default_h => [ \&default, "text" ], ); $output = ''; $p->parse($input); $p->eof; return $output; } #---------------------------------------------------------------------------- sub default { $output .= shift; } #---------------------------------------------------------------------------- sub tag_start { my ($tagname, $pos, $text) = @_; if (exists $url_tags{$tagname}) { ATTR: while (4 <= @$pos) { my ($k_offset, $k_len, $v_offset, $v_len) = splice @$pos, -4; my $attr = lc(substr($text, $k_offset, $k_len)); if (exists $url_tags{$tagname}{$attr}) { my $val = substr($text, $v_offset, $v_len); $val =~ s/^([\'\"])(.*)\1$/$2/; substr($text, $v_offset, $v_len) = '"'.encode_url($val).'"'; last ATTR; } } } $output .= $text; } #---------------------------------------------------------------------------- sub encode_url { my $str = shift; return encode_entities(decode_entities($str)); } #---------------------------------------------------------------------------- 1;