| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package Data::Validate::Domain; |
|
2
|
|
|
|
|
|
|
|
|
3
|
1
|
|
|
1
|
|
67748
|
use strict; |
|
|
1
|
|
|
|
|
1
|
|
|
|
1
|
|
|
|
|
22
|
|
|
4
|
1
|
|
|
1
|
|
3
|
use warnings; |
|
|
1
|
|
|
|
|
1
|
|
|
|
1
|
|
|
|
|
31
|
|
|
5
|
|
|
|
|
|
|
|
|
6
|
|
|
|
|
|
|
our $VERSION = '0.13'; |
|
7
|
|
|
|
|
|
|
|
|
8
|
1
|
|
|
1
|
|
623
|
use Net::Domain::TLD qw(tld_exists); |
|
|
1
|
|
|
|
|
7331
|
|
|
|
1
|
|
|
|
|
105
|
|
|
9
|
|
|
|
|
|
|
|
|
10
|
1
|
|
|
1
|
|
8
|
use Exporter qw( import ); |
|
|
1
|
|
|
|
|
1
|
|
|
|
1
|
|
|
|
|
531
|
|
|
11
|
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
## no critic (Modules::ProhibitAutomaticExportation) |
|
13
|
|
|
|
|
|
|
our @EXPORT = qw( |
|
14
|
|
|
|
|
|
|
is_domain |
|
15
|
|
|
|
|
|
|
is_hostname |
|
16
|
|
|
|
|
|
|
is_domain_label |
|
17
|
|
|
|
|
|
|
); |
|
18
|
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
sub new { |
|
20
|
5
|
|
|
5
|
1
|
5
|
my $class = shift; |
|
21
|
|
|
|
|
|
|
|
|
22
|
5
|
|
33
|
|
|
30
|
return bless {@_}, ref($class) || $class; |
|
23
|
|
|
|
|
|
|
} |
|
24
|
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
# ------------------------------------------------------------------------------- |
|
26
|
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
sub is_domain { |
|
28
|
58
|
|
|
58
|
1
|
11739
|
my ( $value, $opt ) = _maybe_oo(@_); |
|
29
|
|
|
|
|
|
|
|
|
30
|
58
|
|
|
|
|
83
|
my ( $hostname, $bits ) = _domain_labels( $value, $opt ); |
|
31
|
|
|
|
|
|
|
|
|
32
|
58
|
100
|
|
|
|
125
|
return unless $bits; |
|
33
|
|
|
|
|
|
|
|
|
34
|
44
|
|
|
|
|
46
|
my $tld = $bits->[-1]; |
|
35
|
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
# domain_allow_single_label set to true disables this check |
|
37
|
44
|
100
|
|
|
|
67
|
unless ( $opt->{domain_allow_single_label} ) { |
|
38
|
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
# All domains have more then 1 label (neely.cx good, com not good) |
|
40
|
39
|
100
|
|
|
|
24
|
return if @{$bits} < 2; |
|
|
39
|
|
|
|
|
81
|
|
|
41
|
|
|
|
|
|
|
} |
|
42
|
|
|
|
|
|
|
|
|
43
|
35
|
100
|
|
|
|
56
|
return $hostname if $opt->{domain_disable_tld_validation}; |
|
44
|
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
# If the option to enable domain_private_tld is enabled |
|
46
|
|
|
|
|
|
|
# and a private domain is specified, then we return if that matches |
|
47
|
34
|
100
|
66
|
|
|
78
|
if ( exists $opt->{domain_private_tld} |
|
48
|
|
|
|
|
|
|
&& ref( $opt->{domain_private_tld} ) ) { |
|
49
|
13
|
|
|
|
|
15
|
my $lc_tld = lc($tld); |
|
50
|
13
|
100
|
|
|
|
38
|
if ( ref( $opt->{domain_private_tld} ) eq 'HASH' ) { |
|
51
|
8
|
100
|
|
|
|
15
|
if ( exists $opt->{domain_private_tld}->{$lc_tld} ) { |
|
52
|
6
|
|
|
|
|
25
|
return $hostname; |
|
53
|
|
|
|
|
|
|
} |
|
54
|
|
|
|
|
|
|
} |
|
55
|
|
|
|
|
|
|
else { |
|
56
|
5
|
100
|
|
|
|
22
|
if ( $tld =~ $opt->{domain_private_tld} ) { |
|
57
|
3
|
|
|
|
|
15
|
return $hostname; |
|
58
|
|
|
|
|
|
|
} |
|
59
|
|
|
|
|
|
|
} |
|
60
|
|
|
|
|
|
|
} |
|
61
|
|
|
|
|
|
|
|
|
62
|
|
|
|
|
|
|
# Verify domain has a valid TLD |
|
63
|
25
|
100
|
|
|
|
48
|
return unless tld_exists($tld); |
|
64
|
|
|
|
|
|
|
|
|
65
|
18
|
|
|
|
|
149
|
return $hostname; |
|
66
|
|
|
|
|
|
|
} |
|
67
|
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
# ------------------------------------------------------------------------------- |
|
69
|
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
sub is_hostname { |
|
71
|
11
|
|
|
11
|
1
|
2926
|
my ( $value, $opt ) = _maybe_oo(@_); |
|
72
|
|
|
|
|
|
|
|
|
73
|
11
|
|
|
|
|
14
|
my ($hostname) = _domain_labels( $value, $opt ); |
|
74
|
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
# We do not verify TLD for hostnames, as hostname.subhost is a valid hostname |
|
76
|
|
|
|
|
|
|
|
|
77
|
11
|
|
|
|
|
39
|
return $hostname; |
|
78
|
|
|
|
|
|
|
} |
|
79
|
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
sub _domain_labels { |
|
81
|
69
|
|
|
69
|
|
65
|
my ( $value, $opt ) = @_; |
|
82
|
|
|
|
|
|
|
|
|
83
|
69
|
100
|
|
|
|
117
|
return unless defined($value); |
|
84
|
|
|
|
|
|
|
|
|
85
|
67
|
|
|
|
|
48
|
my $length = length($value); |
|
86
|
67
|
100
|
66
|
|
|
231
|
return if $length < 0 || $length > 255; |
|
87
|
|
|
|
|
|
|
|
|
88
|
65
|
100
|
|
|
|
124
|
my $trailing_dot = $value =~ s/\.\z// ? q{.} : q{}; |
|
89
|
|
|
|
|
|
|
|
|
90
|
65
|
|
|
|
|
43
|
my @bits; |
|
91
|
65
|
|
|
|
|
136
|
foreach my $label ( split /\./, $value, -1 ) { |
|
92
|
111
|
|
|
|
|
123
|
my $bit = is_domain_label( $label, $opt ); |
|
93
|
111
|
100
|
|
|
|
145
|
return unless defined $bit; |
|
94
|
99
|
|
|
|
|
119
|
push( @bits, $bit ); |
|
95
|
|
|
|
|
|
|
} |
|
96
|
|
|
|
|
|
|
|
|
97
|
53
|
100
|
|
|
|
89
|
return unless @bits; |
|
98
|
|
|
|
|
|
|
|
|
99
|
50
|
|
|
|
|
129
|
return ( join( '.', @bits ) . $trailing_dot, \@bits ); |
|
100
|
|
|
|
|
|
|
} |
|
101
|
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
sub is_domain_label { |
|
103
|
123
|
|
|
123
|
1
|
4395
|
my ( $value, $opt ) = _maybe_oo(@_); |
|
104
|
|
|
|
|
|
|
|
|
105
|
123
|
100
|
|
|
|
173
|
return unless defined($value); |
|
106
|
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
# Fix Bug: 41033 |
|
108
|
122
|
100
|
|
|
|
172
|
return if ( $value =~ /\n/ ); |
|
109
|
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
# bail if we are dealing with more then just a hostname |
|
111
|
121
|
50
|
|
|
|
141
|
return if ( $value =~ /\./ ); |
|
112
|
121
|
|
|
|
|
88
|
my $length = length($value); |
|
113
|
121
|
|
|
|
|
65
|
my $hostname; |
|
114
|
121
|
100
|
100
|
|
|
332
|
if ( $length == 1 ) { |
|
|
|
100
|
|
|
|
|
|
|
115
|
8
|
50
|
|
|
|
14
|
if ( $opt->{domain_allow_underscore} ) { |
|
116
|
0
|
|
|
|
|
0
|
($hostname) = $value =~ /^([0-9A-Za-z\_])$/; |
|
117
|
|
|
|
|
|
|
} |
|
118
|
|
|
|
|
|
|
else { |
|
119
|
8
|
|
|
|
|
16
|
($hostname) = $value =~ /^([0-9A-Za-z])$/; |
|
120
|
|
|
|
|
|
|
} |
|
121
|
|
|
|
|
|
|
} |
|
122
|
|
|
|
|
|
|
elsif ( $length > 1 && $length <= 63 ) { |
|
123
|
109
|
100
|
|
|
|
133
|
if ( $opt->{domain_allow_underscore} ) { |
|
124
|
9
|
|
|
|
|
27
|
($hostname) |
|
125
|
|
|
|
|
|
|
= $value =~ /^([0-9A-Za-z\_][0-9A-Za-z\-\_]*[0-9A-Za-z])$/; |
|
126
|
|
|
|
|
|
|
} |
|
127
|
|
|
|
|
|
|
else { |
|
128
|
100
|
|
|
|
|
300
|
($hostname) |
|
129
|
|
|
|
|
|
|
= $value =~ /^([0-9A-Za-z][0-9A-Za-z\-]*[0-9A-Za-z])$/; |
|
130
|
|
|
|
|
|
|
} |
|
131
|
|
|
|
|
|
|
} |
|
132
|
|
|
|
|
|
|
else { |
|
133
|
4
|
|
|
|
|
8
|
return; |
|
134
|
|
|
|
|
|
|
} |
|
135
|
117
|
|
|
|
|
164
|
return $hostname; |
|
136
|
|
|
|
|
|
|
} |
|
137
|
|
|
|
|
|
|
|
|
138
|
|
|
|
|
|
|
sub _maybe_oo { |
|
139
|
192
|
100
|
|
192
|
|
239
|
if ( ref $_[0] ) { |
|
140
|
15
|
|
|
|
|
26
|
return @_[ 1, 0 ]; |
|
141
|
|
|
|
|
|
|
} |
|
142
|
|
|
|
|
|
|
else { |
|
143
|
177
|
100
|
|
|
|
334
|
return ( $_[0], ( defined $_[1] ? $_[1] : {} ) ); |
|
144
|
|
|
|
|
|
|
} |
|
145
|
|
|
|
|
|
|
} |
|
146
|
|
|
|
|
|
|
|
|
147
|
|
|
|
|
|
|
1; |
|
148
|
|
|
|
|
|
|
|
|
149
|
|
|
|
|
|
|
# ABSTRACT: Domain and host name validation |
|
150
|
|
|
|
|
|
|
|
|
151
|
|
|
|
|
|
|
__END__ |