Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision ecfae06f

Von Moritz Bunkus vor mehr als 10 Jahren hinzugefügt

  • ID ecfae06f7ab8715b708ac70da907328a7c272b72
  • Vorgänger 551d4b78
  • Nachfolger bb3360db

AttrHTML: Model-Helper für sicheres HTML in RDB-Models

Unterschiede anzeigen:

SL/DB/Helper/AttrHTML.pm
1
package SL::DB::Helper::AttrHTML;
2

  
3
use strict;
4

  
5
use parent qw(Exporter);
6
our @EXPORT = qw(attr_html);
7

  
8
use utf8;
9
use Carp;
10
use Encode ();
11
use HTML::Restrict ();
12
use HTML::Parser;
13

  
14
my %stripper;
15

  
16
sub _strip_html {
17
  my ($value) = @_;
18

  
19
  if (!%stripper) {
20
    %stripper = ( parser => HTML::Parser->new );
21

  
22
    $stripper{parser}->handler(text => sub { $stripper{text} .= $_[1]; });
23
  }
24

  
25
  $stripper{text} = '';
26
  $stripper{parser}->parse($value);
27
  $stripper{parser}->eof;
28

  
29
  return delete $stripper{text};
30
}
31

  
32
sub attr_html {
33
  my ($package, $attributes, %params) = @_;
34

  
35
  # Set default parameters:
36
  $params{with_stripped}   //= 1;
37
  $params{with_restricted} //= 1;
38
  $params{allowed_tags}    //= { map { ($_ => ['/']) } qw(b strong i em u ul ol li sub sup s strike br p div) };
39
  $attributes                = [ $attributes ] unless ref($attributes) eq 'ARRAY';
40

  
41
  # Do the work
42
  foreach my $attribute (@{ $attributes }) {
43
    _make_stripped(  $package, $attribute, %params) if ($params{with_stripped});
44
    _make_restricted($package, $attribute, %params) if ($params{with_restricted});
45
  }
46
}
47

  
48
sub _make_stripped {
49
  my ($package, $attribute, %params) = @_;
50

  
51
  no strict 'refs';
52

  
53
  *{ $package . '::' . $attribute . '_as_stripped_html' } = sub {
54
    my ($self, $value) = @_;
55

  
56
    return $self->$attribute(_strip_html($value)) if @_ > 1;
57
    return _strip_html($self->$attribute);
58
  };
59
}
60

  
61
sub _make_restricted {
62
  my ($package, $attribute, %params) = @_;
63

  
64
  no strict 'refs';
65

  
66
  my $cleaner = HTML::Restrict->new(rules => $params{allowed_tags});
67

  
68
  *{ $package . '::' . $attribute . '_as_restricted_html' } = sub {
69
    my ($self, $value) = @_;
70

  
71
    return $self->$attribute($cleaner->process($value)) if @_ > 1;
72
    return $cleaner->process($self->$attribute);
73
  };
74
}
75

  
76
1;
77
__END__
78

  
79
=pod
80

  
81
=encoding utf8
82

  
83
=head1 NAME
84

  
85
SL::DB::Helper::AttrHTML - Attribute helper for stripping
86
all/restricting to wanted HTML tags in columns
87

  
88
=head1 SYNOPSIS
89

  
90
  # In a Rose model:
91
  use SL::DB::Helper::AttrHTML;
92
  __PACKAGE__->attr_as_html(
93
    'content',
94
    with_stripped => 0,
95
    allowed_tags  => { b => [ '/' ], i => [ '/' ] },
96
  );
97

  
98
  # Use in HTML templates (no usage of HTML.escape() here!):
99
  <div>
100
    This is the post's content:<br>
101
    [% SELF.obj.content_as_restricted_html %]
102
  </div>
103

  
104
  # Writing to it from a form:
105
  <form method="post">
106
    ...
107
    [% L.textarea_tag('post.content_as_restricted_html', SELF.obj.content_as_restricted_html) %]
108
  </form>
109

  
110
=head1 OVERVIEW
111

  
112
Sometimes you want an HTML editor on your web page. However, you only
113
want to allow certain tags. You also need to repeat that stuff when
114
displaying it without risking HTML/JavaScript injection attacks.
115

  
116
This plugin provides two helper methods for an attribute:
117
C<attribute_as_stripped_html> which removes all HTML tags, and
118
C<attribute_as_restricted_html> which removes all but a list of safe
119
HTML tags. Both are simple accessor methods.
120

  
121
=head1 FUNCTIONS
122

  
123
=over 4
124

  
125
=item C<attr_html $attributes, [%params]>
126

  
127
Package method. Call with the name of the attributes (either a scalar
128
for a single attribute or an array reference for multiple attributes)
129
for which the helper methods should be created.
130

  
131
C<%params> can include the following options:
132

  
133
=over 2
134

  
135
=item * C<with_stripped> is a scalar that controls the creation of the
136
C<attribute_as_stripped_html> method. It is on by default.
137

  
138
=item * C<with_restricted> is a scalar that controls the creation of the
139
C<attribute_as_restricted_html> method. It is on by default. If it is
140
on then the parameter C<allowed_tags> contains the tags that are kept
141
by this method.
142

  
143
=item * C<allowed_tags> must be a hash reference containing the tags
144
and attributes to keep. It follows the same structural layout as the
145
C<rules> parameter of L<HTML::Restrict/new>. Only relevant if
146
C<with_restricted> is trueish. It defaults to allow the following tags
147
without any attribute safe the trailing slash: C<b i u ul ol li sub
148
sup strike br p div>.
149

  
150
=back
151

  
152
=back
153

  
154
=head1 BUGS
155

  
156
Nothing here yet.
157

  
158
=head1 AUTHOR
159

  
160
Moritz Bunkus E<lt>m.bunkus@linet-services.deE<gt>
161

  
162
=cut
SL/InstallationCheck.pm
28 28
  { name => "FCGI",            version => '0.72',  url => "http://search.cpan.org/~mstrout/",   debian => 'libfcgi-perl' },
29 29
  { name => "File::Copy::Recursive",               url => "http://search.cpan.org/~dmuey/",     debian => 'libfile-copy-recursive-perl' },
30 30
  { name => "GD",                                  url => "http://search.cpan.org/~lds/",       debian => 'libgd-gd2-perl', },
31
  { name => 'HTML::Parser',                        url => 'http://search.cpan.org/~gaas/',      debian => 'libhtml-parser-perl', },
32
  { name => 'HTML::Restrict',                      url => 'http://search.cpan.org/~oalders/', },
31 33
  { name => "Image::Info",                         url => "http://search.cpan.org/~srezic/",    debian => 'libimage-info-perl' },
32 34
  { name => "JSON",                                url => "http://search.cpan.org/~makamaka",   debian => 'libjson-perl' },
33 35
  { name => "List::MoreUtils", version => '0.21',  url => "http://search.cpan.org/~vparseval/", debian => 'liblist-moreutils-perl' },

Auch abrufbar als: Unified diff