|  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__  |