← Index
NYTProf Performance Profile   « line view »
For /usr/local/bin/sa-learn
  Run on Tue Nov 7 05:38:10 2017
Reported on Tue Nov 7 06:16:04 2017

Filename/usr/local/lib/perl5/site_perl/Mail/SpamAssassin/Plugin/MIMEHeader.pm
StatementsExecuted 953 statements in 15.4ms
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
461113.7ms38.4msMail::SpamAssassin::Plugin::MIMEHeader::::__ANON__[:160]Mail::SpamAssassin::Plugin::MIMEHeader::__ANON__[:160]
4611321µs321µsMail::SpamAssassin::Plugin::MIMEHeader::::CORE:matchMail::SpamAssassin::Plugin::MIMEHeader::CORE:match (opcode)
4611217µs217µsMail::SpamAssassin::Plugin::MIMEHeader::::CORE:substMail::SpamAssassin::Plugin::MIMEHeader::CORE:subst (opcode)
11172µs80µsMail::SpamAssassin::Plugin::MIMEHeader::::BEGIN@60Mail::SpamAssassin::Plugin::MIMEHeader::BEGIN@60
11159µs299µsMail::SpamAssassin::Plugin::MIMEHeader::::newMail::SpamAssassin::Plugin::MIMEHeader::new
11147µs198µsMail::SpamAssassin::Plugin::MIMEHeader::::set_configMail::SpamAssassin::Plugin::MIMEHeader::set_config
11131µs64µsMail::SpamAssassin::Plugin::MIMEHeader::::BEGIN@61Mail::SpamAssassin::Plugin::MIMEHeader::BEGIN@61
11130µs200µsMail::SpamAssassin::Plugin::MIMEHeader::::BEGIN@70Mail::SpamAssassin::Plugin::MIMEHeader::BEGIN@70
11128µs33µsMail::SpamAssassin::Plugin::MIMEHeader::::BEGIN@62Mail::SpamAssassin::Plugin::MIMEHeader::BEGIN@62
11124µs189µsMail::SpamAssassin::Plugin::MIMEHeader::::BEGIN@67Mail::SpamAssassin::Plugin::MIMEHeader::BEGIN@67
11124µs153µsMail::SpamAssassin::Plugin::MIMEHeader::::BEGIN@68Mail::SpamAssassin::Plugin::MIMEHeader::BEGIN@68
11122µs96µsMail::SpamAssassin::Plugin::MIMEHeader::::BEGIN@63Mail::SpamAssassin::Plugin::MIMEHeader::BEGIN@63
11116µs16µsMail::SpamAssassin::Plugin::MIMEHeader::::BEGIN@66Mail::SpamAssassin::Plugin::MIMEHeader::BEGIN@66
11113µs13µsMail::SpamAssassin::Plugin::MIMEHeader::::BEGIN@65Mail::SpamAssassin::Plugin::MIMEHeader::BEGIN@65
0000s0sMail::SpamAssassin::Plugin::MIMEHeader::::eval_hook_calledMail::SpamAssassin::Plugin::MIMEHeader::eval_hook_called
0000s0sMail::SpamAssassin::Plugin::MIMEHeader::::finish_testsMail::SpamAssassin::Plugin::MIMEHeader::finish_tests
Call graph for these subroutines as a Graphviz dot language file.
Line State
ments
Time
on line
Calls Time
in subs
Code
1# <@LICENSE>
2# Licensed to the Apache Software Foundation (ASF) under one or more
3# contributor license agreements. See the NOTICE file distributed with
4# this work for additional information regarding copyright ownership.
5# The ASF licenses this file to you under the Apache License, Version 2.0
6# (the "License"); you may not use this file except in compliance with
7# the License. You may obtain a copy of the License at:
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16# </@LICENSE>
17
18=head1 NAME
19
20MIMEHeader - perform regexp tests against MIME headers
21
22=head1 SYNOPSIS
23
24 loadplugin Mail::SpamAssassin::Plugin::MIMEHeader
25 mimeheader NAME_OF_RULE Content-Id =~ /foo/
26
27=head1 DESCRIPTION
28
29This plugin allows regexp rules to be written against MIME headers in the
30message.
31
32=head1 RULE DEFINITIONS AND PRIVILEGED SETTINGS
33
34=over 4
35
36=item mimeheader NAME_OF_RULE Header-Name =~ /pattern/modifiers
37
38Specify a rule. C<NAME_OF_RULE> is the name of the rule to be used,
39C<Header-Name> is the name of the MIME header to check, and
40C</pattern/modifiers> is the Perl regular expression to match against this.
41
42Note that in a message of multiple parts, each header will be checked
43against the pattern separately. In other words, if multiple parts
44have a 'Content-Type' header, each header's value will be tested
45individually as a separate string.
46
47Header names are considered case-insensitive.
48
49The header values are normally cleaned up a little; for example, whitespace
50around the newline character in "folded" headers will be replaced with a single
51space. Append C<:raw> to the header name to retrieve the raw, undecoded value,
52including pristine whitespace, instead.
53
54=back
55
56=cut
57
58package Mail::SpamAssassin::Plugin::MIMEHeader;
59
60276µs289µs
# spent 80µs (72+8) within Mail::SpamAssassin::Plugin::MIMEHeader::BEGIN@60 which was called: # once (72µs+8µs) by Mail::SpamAssassin::PluginHandler::load_plugin at line 60
use strict;
# spent 80µs making 1 call to Mail::SpamAssassin::Plugin::MIMEHeader::BEGIN@60 # spent 8µs making 1 call to strict::import
61279µs297µs
# spent 64µs (31+33) within Mail::SpamAssassin::Plugin::MIMEHeader::BEGIN@61 which was called: # once (31µs+33µs) by Mail::SpamAssassin::PluginHandler::load_plugin at line 61
use warnings;
# spent 64µs making 1 call to Mail::SpamAssassin::Plugin::MIMEHeader::BEGIN@61 # spent 33µs making 1 call to warnings::import
62266µs238µs
# spent 33µs (28+5) within Mail::SpamAssassin::Plugin::MIMEHeader::BEGIN@62 which was called: # once (28µs+5µs) by Mail::SpamAssassin::PluginHandler::load_plugin at line 62
use bytes;
# spent 33µs making 1 call to Mail::SpamAssassin::Plugin::MIMEHeader::BEGIN@62 # spent 5µs making 1 call to bytes::import
63269µs2169µs
# spent 96µs (22+73) within Mail::SpamAssassin::Plugin::MIMEHeader::BEGIN@63 which was called: # once (22µs+73µs) by Mail::SpamAssassin::PluginHandler::load_plugin at line 63
use re 'taint';
# spent 96µs making 1 call to Mail::SpamAssassin::Plugin::MIMEHeader::BEGIN@63 # spent 73µs making 1 call to re::import
64
65262µs113µs
# spent 13µs within Mail::SpamAssassin::Plugin::MIMEHeader::BEGIN@65 which was called: # once (13µs+0s) by Mail::SpamAssassin::PluginHandler::load_plugin at line 65
use Mail::SpamAssassin::Plugin;
66263µs116µs
# spent 16µs within Mail::SpamAssassin::Plugin::MIMEHeader::BEGIN@66 which was called: # once (16µs+0s) by Mail::SpamAssassin::PluginHandler::load_plugin at line 66
use Mail::SpamAssassin::Conf;
67268µs2354µs
# spent 189µs (24+165) within Mail::SpamAssassin::Plugin::MIMEHeader::BEGIN@67 which was called: # once (24µs+165µs) by Mail::SpamAssassin::PluginHandler::load_plugin at line 67
use Mail::SpamAssassin::Logger;
# spent 189µs making 1 call to Mail::SpamAssassin::Plugin::MIMEHeader::BEGIN@67 # spent 165µs making 1 call to Exporter::import
68284µs2283µs
# spent 153µs (24+130) within Mail::SpamAssassin::Plugin::MIMEHeader::BEGIN@68 which was called: # once (24µs+130µs) by Mail::SpamAssassin::PluginHandler::load_plugin at line 68
use Mail::SpamAssassin::Util qw(untaint_var);
# spent 153µs making 1 call to Mail::SpamAssassin::Plugin::MIMEHeader::BEGIN@68 # spent 130µs making 1 call to Exporter::import
69
7021.41ms2369µs
# spent 200µs (30+170) within Mail::SpamAssassin::Plugin::MIMEHeader::BEGIN@70 which was called: # once (30µs+170µs) by Mail::SpamAssassin::PluginHandler::load_plugin at line 70
use vars qw(@ISA @TEMPORARY_METHODS);
# spent 200µs making 1 call to Mail::SpamAssassin::Plugin::MIMEHeader::BEGIN@70 # spent 170µs making 1 call to vars::import
71121µs@ISA = qw(Mail::SpamAssassin::Plugin);
72
7312µs@TEMPORARY_METHODS = ();
74
75# ---------------------------------------------------------------------------
76
77# constructor
78
# spent 299µs (59+240) within Mail::SpamAssassin::Plugin::MIMEHeader::new which was called: # once (59µs+240µs) by Mail::SpamAssassin::PluginHandler::load_plugin at line 1 of (eval 77)[Mail/SpamAssassin/PluginHandler.pm:129]
sub new {
7912µs my $class = shift;
8012µs my $samain = shift;
81
82 # some boilerplate...
8312µs $class = ref($class) || $class;
84120µs142µs my $self = $class->SUPER::new($samain);
# spent 42µs making 1 call to Mail::SpamAssassin::Plugin::new
8512µs bless ($self, $class);
86
8717µs1198µs $self->set_config($samain->{conf});
88
8919µs return $self;
90}
91
92# ---------------------------------------------------------------------------
93
94
# spent 198µs (47+152) within Mail::SpamAssassin::Plugin::MIMEHeader::set_config which was called: # once (47µs+152µs) by Mail::SpamAssassin::Plugin::MIMEHeader::new at line 87
sub set_config {
9512µs my($self, $conf) = @_;
9612µs my @cmds;
97
9812µs my $pluginobj = $self; # allow use inside the closure below
99
100 push (@cmds, {
101 setting => 'mimeheader',
102 is_priv => 1,
103
# spent 38.4ms (13.7+24.7) within Mail::SpamAssassin::Plugin::MIMEHeader::__ANON__[/usr/local/lib/perl5/site_perl/Mail/SpamAssassin/Plugin/MIMEHeader.pm:160] which was called 46 times, avg 834µs/call: # 46 times (13.7ms+24.7ms) by Mail::SpamAssassin::Conf::Parser::parse at line 438 of Mail/SpamAssassin/Conf/Parser.pm, avg 834µs/call
code => sub {
10446274µs my ($self, $key, $value, $line) = @_;
10546273µs local ($1,$2,$3,$4);
10646791µs46321µs if ($value !~ /^(\S+)\s+(\S+)\s*([\=\!]\~)\s*(.+)$/) {
# spent 321µs making 46 calls to Mail::SpamAssassin::Plugin::MIMEHeader::CORE:match, avg 7µs/call
107 return $Mail::SpamAssassin::Conf::INVALID_VALUE;
108 }
109
110 # provide stricter syntax for rule name!?
11146314µs461.14ms my $rulename = untaint_var($1);
# spent 1.14ms making 46 calls to Mail::SpamAssassin::Util::untaint_var, avg 25µs/call
11246150µs my $hdrname = $2;
11346173µs my $negated = ($3 eq '!~') ? 1 : 0;
11446126µs my $pattern = $4;
115
11646410µs468.68ms return unless $self->{parser}->is_delimited_regexp_valid($rulename, $pattern);
# spent 8.68ms making 46 calls to Mail::SpamAssassin::Conf::Parser::is_delimited_regexp_valid, avg 189µs/call
117
11846424µs468.40ms $pattern = Mail::SpamAssassin::Util::make_qr($pattern);
# spent 8.40ms making 46 calls to Mail::SpamAssassin::Util::make_qr, avg 183µs/call
1194682µs return $Mail::SpamAssassin::Conf::INVALID_VALUE unless $pattern;
120
12146642µs $self->{mimeheader_tests}->{$rulename} = {
122 hdr => $hdrname,
123 negated => $negated,
124 if_unset => '', # TODO!
125 pattern => $pattern
126 };
127
128 # now here's a hack; generate a fake eval rule function to
129 # call this rule's _real_ code!
130 # TODO: we should have a more elegant way for new rule types to
131 # be defined
13246112µs my $evalfn = "_mimeheader_eval_$rulename";
13346589µs46217µs $evalfn =~ s/[^a-zA-Z0-9_]/_/gs;
# spent 217µs making 46 calls to Mail::SpamAssassin::Plugin::MIMEHeader::CORE:subst, avg 5µs/call
134
135 # don't redefine the subroutine if it already exists!
136 # this causes lots of annoying warnings and such during things like
137 # "make test".
138921.01ms return if (defined &{'Mail::SpamAssassin::Plugin::MIMEHeader::'.$evalfn});
139
14046443µs463.94ms $self->{parser}->add_test($rulename, $evalfn."()",
# spent 3.94ms making 46 calls to Mail::SpamAssassin::Conf::Parser::add_test, avg 86µs/call
141 $Mail::SpamAssassin::Conf::TYPE_BODY_EVALS);
142
14346157µs my $evalcode = '
144 sub Mail::SpamAssassin::Plugin::MIMEHeader::'.$evalfn.' {
145 $_[0]->eval_hook_called($_[1], q{'.$rulename.'});
146 }
147 ';
148
149 eval
150 $evalcode . '; 1'
151465.89ms or do {
# spent 16µs executing statements in 2 string evals (merged) # spent 13µs executing statements in string eval # spent 10µs executing statements in 2 string evals (merged) # spent 8µs executing statements in string eval # spent 7µs executing statements in string eval # spent 6µs executing statements in string eval # spent 6µs executing statements in string eval # spent 6µs executing statements in string eval # spent 6µs executing statements in string eval # spent 6µs executing statements in string eval # spent 5µs executing statements in string eval # spent 5µs executing statements in string eval # spent 5µs executing statements in string eval # spent 5µs executing statements in string eval # spent 5µs executing statements in string eval # spent 5µs executing statements in string eval # spent 5µs executing statements in string eval # spent 5µs executing statements in string eval # spent 5µs executing statements in string eval # spent 5µs executing statements in string eval # spent 5µs executing statements in string eval # spent 5µs executing statements in string eval # spent 5µs executing statements in string eval # spent 5µs executing statements in string eval # spent 5µs executing statements in string eval # spent 5µs executing statements in string eval # spent 5µs executing statements in string eval # spent 5µs executing statements in string eval # spent 5µs executing statements in string eval # spent 5µs executing statements in string eval # spent 5µs executing statements in string eval # spent 5µs executing statements in string eval # spent 5µs executing statements in string eval # spent 5µs executing statements in string eval # spent 5µs executing statements in string eval # spent 5µs executing statements in string eval # spent 5µs executing statements in string eval # spent 5µs executing statements in string eval # spent 5µs executing statements in string eval # spent 5µs executing statements in string eval # spent 5µs executing statements in string eval # spent 5µs executing statements in string eval # spent 5µs executing statements in string eval # spent 5µs executing statements in string eval
152 my $eval_stat = $@ ne '' ? $@ : "errno=$!"; chomp $eval_stat;
153 warn "mimeheader: plugin error: $eval_stat\n";
154 return $Mail::SpamAssassin::Conf::INVALID_VALUE;
155 };
156
15746444µs461.96ms $pluginobj->register_eval_rule($evalfn);
# spent 1.96ms making 46 calls to Mail::SpamAssassin::Plugin::register_eval_rule, avg 43µs/call
158
15946993µs push @TEMPORARY_METHODS, "Mail::SpamAssassin::Plugin::MIMEHeader::${evalfn}";
160 }
161122µs });
162
163115µs1152µs $conf->{parser}->register_commands(\@cmds);
164}
165
166# ---------------------------------------------------------------------------
167
168sub eval_hook_called {
169 my ($pobj, $scanner, $rulename) = @_;
170
171 my $rule = $scanner->{conf}->{mimeheader_tests}->{$rulename};
172 my $hdr = $rule->{hdr};
173 my $negated = $rule->{negated};
174 my $if_unset = $rule->{if_unset};
175 my $pattern = $rule->{pattern};
176
177
178 my $getraw;
179 if ($hdr =~ s/:raw$//i) {
180 $getraw = 1;
181 } else {
182 $getraw = 0;
183 }
184
185 foreach my $p ($scanner->{msg}->find_parts(qr/./)) {
186 my $val;
187 if ($getraw) {
188 $val = $p->raw_header($hdr);
189 } else {
190 $val = $p->get_header($hdr);
191 }
192 $val ||= $if_unset;
193
194 if ($val =~ ${pattern}) {
195 return ($negated ? 0 : 1);
196 }
197 }
198
199 return ($negated ? 1 : 0);
200}
201
202# ---------------------------------------------------------------------------
203
204sub finish_tests {
205 my ($self, $params) = @_;
206
207 foreach my $method (@TEMPORARY_METHODS) {
208 undef &{$method};
209 }
210 @TEMPORARY_METHODS = (); # clear for next time
211}
212
213# ---------------------------------------------------------------------------
214
215125µs1;
 
# spent 321µs within Mail::SpamAssassin::Plugin::MIMEHeader::CORE:match which was called 46 times, avg 7µs/call: # 46 times (321µs+0s) by Mail::SpamAssassin::Plugin::MIMEHeader::__ANON__[/usr/local/lib/perl5/site_perl/Mail/SpamAssassin/Plugin/MIMEHeader.pm:160] at line 106, avg 7µs/call
sub Mail::SpamAssassin::Plugin::MIMEHeader::CORE:match; # opcode
# spent 217µs within Mail::SpamAssassin::Plugin::MIMEHeader::CORE:subst which was called 46 times, avg 5µs/call: # 46 times (217µs+0s) by Mail::SpamAssassin::Plugin::MIMEHeader::__ANON__[/usr/local/lib/perl5/site_perl/Mail/SpamAssassin/Plugin/MIMEHeader.pm:160] at line 133, avg 5µs/call
sub Mail::SpamAssassin::Plugin::MIMEHeader::CORE:subst; # opcode