File Coverage

lib/Haineko/SMTPD/RFC5322.pm
Criterion Covered Total %
statement 15 15 100.0
branch 5 6 83.3
condition 2 4 50.0
subroutine 4 4 100.0
pod 2 2 100.0
total 28 31 90.3


line stmt bran cond sub pod time code
1             package Haineko::SMTPD::RFC5322;
2 3     3   3317 use strict;
  3         6  
  3         275  
3 3     3   18 use warnings;
  3         4  
  3         2540  
4              
5             # Regular expression of valid RFC-5322 email address()
6             my $Rx = { 'rfc5322' => undef, 'ignored' => undef, 'domain' => undef, };
7              
8             # See http://www.ietf.org/rfc/rfc5322.txt
9             # or http://www.ex-parrot.com/pdw/Mail-RFC822-Address.html ...
10             # addr-spec = local-part "@" domain
11             # local-part = dot-atom / quoted-string / obs-local-part
12             # domain = dot-atom / domain-literal / obs-domain
13             # domain-literal = [CFWS] "[" *([FWS] dtext ) [FWS] "]" [CFWS]
14             # dtext = %d33-90 / ; Printable US-ASCII
15             # %d94-126 / ; characters not including
16             # obs-dtext ; "[", "]", or "\"
17             #
18             #
19             BUILD_REGULAR_EXPRESSIONS: {
20             my $atom = qr([a-zA-Z0-9_!#\$\%&'*+/=?\^`{}~|\-]+)o;
21             my $quoted_string = qr/"(?:\\[^\r\n]|[^\\"])*"/o;
22             my $domain_literal = qr/\[(?:\\[\x01-\x09\x0B-\x0c\x0e-\x7f]|[\x21-\x5a\x5e-\x7e])*\]/o;
23             my $dot_atom = qr/$atom(?:[.]$atom)*/o;
24             my $local_part = qr/(?:$dot_atom|$quoted_string)/o;
25             my $domain = qr/(?:$dot_atom|$domain_literal)/o;
26              
27             $Rx->{'rfc5322'} = qr/$local_part[@]$domain/o;
28             $Rx->{'ignored'} = qr/$local_part[.]*[@]$domain/o;
29             $Rx->{'domain'} = qr/$domain/o;
30             }
31              
32             sub is_emailaddress {
33 17     17 1 4695 my $class = shift;
34 17   50     52 my $email = shift || return 0; # (String) Email address
35              
36 17 50       117 return 0 if $email =~ m{([\x00-\x1f]|\x1f)};
37 17 100       222 return 1 if $email =~ $Rx->{'ignored'};
38 6         27 return 0;
39             }
40              
41             sub is_domainpart {
42 20     20 1 5119 my $class = shift;
43 20   50     65 my $dpart = shift || return 0; # (String) Domain part of an email address
44              
45 20 100       158 return 1 if $dpart =~ m{\A[-0-9A-Za-z.]+[.][A-Za-z]+\z};
46 8         38 return 0;
47             }
48              
49             1;
50             __END__