line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Data::Validate::Domain; |
2
|
|
|
|
|
|
|
|
3
|
1
|
|
|
1
|
|
45983
|
use strict; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
23
|
|
4
|
1
|
|
|
1
|
|
2
|
use warnings; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
34
|
|
5
|
|
|
|
|
|
|
|
6
|
|
|
|
|
|
|
our $VERSION = '0.14'; |
7
|
|
|
|
|
|
|
|
8
|
1
|
|
|
1
|
|
605
|
use Net::Domain::TLD 1.74 qw(tld_exists); |
|
1
|
|
|
|
|
7528
|
|
|
1
|
|
|
|
|
96
|
|
9
|
|
|
|
|
|
|
|
10
|
1
|
|
|
1
|
|
5
|
use Exporter qw( import ); |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
540
|
|
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
|
9
|
my $class = shift; |
21
|
|
|
|
|
|
|
|
22
|
5
|
|
33
|
|
|
29
|
return bless {@_}, ref($class) || $class; |
23
|
|
|
|
|
|
|
} |
24
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
# ------------------------------------------------------------------------------- |
26
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
sub is_domain { |
28
|
58
|
|
|
58
|
1
|
12123
|
my ( $value, $opt ) = _maybe_oo(@_); |
29
|
|
|
|
|
|
|
|
30
|
58
|
|
|
|
|
86
|
my ( $hostname, $bits ) = _domain_labels( $value, $opt ); |
31
|
|
|
|
|
|
|
|
32
|
58
|
100
|
|
|
|
115
|
return unless $bits; |
33
|
|
|
|
|
|
|
|
34
|
44
|
|
|
|
|
41
|
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
|
|
|
|
25
|
return if @{$bits} < 2; |
|
39
|
|
|
|
|
82
|
|
41
|
|
|
|
|
|
|
} |
42
|
|
|
|
|
|
|
|
43
|
35
|
100
|
|
|
|
54
|
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
|
|
|
74
|
if ( exists $opt->{domain_private_tld} |
48
|
|
|
|
|
|
|
&& ref( $opt->{domain_private_tld} ) ) { |
49
|
13
|
|
|
|
|
14
|
my $lc_tld = lc($tld); |
50
|
13
|
100
|
|
|
|
33
|
if ( ref( $opt->{domain_private_tld} ) eq 'HASH' ) { |
51
|
8
|
100
|
|
|
|
14
|
if ( exists $opt->{domain_private_tld}->{$lc_tld} ) { |
52
|
6
|
|
|
|
|
22
|
return $hostname; |
53
|
|
|
|
|
|
|
} |
54
|
|
|
|
|
|
|
} |
55
|
|
|
|
|
|
|
else { |
56
|
5
|
100
|
|
|
|
25
|
if ( $tld =~ $opt->{domain_private_tld} ) { |
57
|
3
|
|
|
|
|
11
|
return $hostname; |
58
|
|
|
|
|
|
|
} |
59
|
|
|
|
|
|
|
} |
60
|
|
|
|
|
|
|
} |
61
|
|
|
|
|
|
|
|
62
|
|
|
|
|
|
|
# Verify domain has a valid TLD |
63
|
25
|
100
|
|
|
|
50
|
return unless tld_exists($tld); |
64
|
|
|
|
|
|
|
|
65
|
18
|
|
|
|
|
151
|
return $hostname; |
66
|
|
|
|
|
|
|
} |
67
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
# ------------------------------------------------------------------------------- |
69
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
sub is_hostname { |
71
|
11
|
|
|
11
|
1
|
3034
|
my ( $value, $opt ) = _maybe_oo(@_); |
72
|
|
|
|
|
|
|
|
73
|
11
|
|
|
|
|
18
|
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
|
|
|
|
|
40
|
return $hostname; |
78
|
|
|
|
|
|
|
} |
79
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
sub _domain_labels { |
81
|
69
|
|
|
69
|
|
54
|
my ( $value, $opt ) = @_; |
82
|
|
|
|
|
|
|
|
83
|
69
|
100
|
|
|
|
112
|
return unless defined($value); |
84
|
|
|
|
|
|
|
|
85
|
67
|
|
|
|
|
57
|
my $length = length($value); |
86
|
67
|
100
|
66
|
|
|
221
|
return if $length < 0 || $length > 255; |
87
|
|
|
|
|
|
|
|
88
|
65
|
100
|
|
|
|
131
|
my $trailing_dot = $value =~ s/\.\z// ? q{.} : q{}; |
89
|
|
|
|
|
|
|
|
90
|
65
|
|
|
|
|
47
|
my @bits; |
91
|
65
|
|
|
|
|
144
|
foreach my $label ( split /\./, $value, -1 ) { |
92
|
111
|
|
|
|
|
120
|
my $bit = is_domain_label( $label, $opt ); |
93
|
111
|
100
|
|
|
|
207
|
return unless defined $bit; |
94
|
99
|
|
|
|
|
137
|
push( @bits, $bit ); |
95
|
|
|
|
|
|
|
} |
96
|
|
|
|
|
|
|
|
97
|
53
|
100
|
|
|
|
76
|
return unless @bits; |
98
|
|
|
|
|
|
|
|
99
|
50
|
|
|
|
|
138
|
return ( join( '.', @bits ) . $trailing_dot, \@bits ); |
100
|
|
|
|
|
|
|
} |
101
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
sub is_domain_label { |
103
|
123
|
|
|
123
|
1
|
4645
|
my ( $value, $opt ) = _maybe_oo(@_); |
104
|
|
|
|
|
|
|
|
105
|
123
|
100
|
|
|
|
178
|
return unless defined($value); |
106
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
# Fix Bug: 41033 |
108
|
122
|
100
|
|
|
|
170
|
return if ( $value =~ /\n/ ); |
109
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
# bail if we are dealing with more then just a hostname |
111
|
121
|
50
|
|
|
|
159
|
return if ( $value =~ /\./ ); |
112
|
121
|
|
|
|
|
80
|
my $length = length($value); |
113
|
121
|
|
|
|
|
77
|
my $hostname; |
114
|
121
|
100
|
100
|
|
|
329
|
if ( $length == 1 ) { |
|
|
100
|
|
|
|
|
|
115
|
8
|
50
|
|
|
|
11
|
if ( $opt->{domain_allow_underscore} ) { |
116
|
0
|
|
|
|
|
0
|
($hostname) = $value =~ /^([0-9A-Za-z\_])$/; |
117
|
|
|
|
|
|
|
} |
118
|
|
|
|
|
|
|
else { |
119
|
8
|
|
|
|
|
18
|
($hostname) = $value =~ /^([0-9A-Za-z])$/; |
120
|
|
|
|
|
|
|
} |
121
|
|
|
|
|
|
|
} |
122
|
|
|
|
|
|
|
elsif ( $length > 1 && $length <= 63 ) { |
123
|
109
|
100
|
|
|
|
129
|
if ( $opt->{domain_allow_underscore} ) { |
124
|
9
|
|
|
|
|
41
|
($hostname) |
125
|
|
|
|
|
|
|
= $value =~ /^([0-9A-Za-z\_][0-9A-Za-z\-\_]*[0-9A-Za-z])$/; |
126
|
|
|
|
|
|
|
} |
127
|
|
|
|
|
|
|
else { |
128
|
100
|
|
|
|
|
303
|
($hostname) |
129
|
|
|
|
|
|
|
= $value =~ /^([0-9A-Za-z][0-9A-Za-z\-]*[0-9A-Za-z])$/; |
130
|
|
|
|
|
|
|
} |
131
|
|
|
|
|
|
|
} |
132
|
|
|
|
|
|
|
else { |
133
|
4
|
|
|
|
|
9
|
return; |
134
|
|
|
|
|
|
|
} |
135
|
117
|
|
|
|
|
161
|
return $hostname; |
136
|
|
|
|
|
|
|
} |
137
|
|
|
|
|
|
|
|
138
|
|
|
|
|
|
|
sub _maybe_oo { |
139
|
192
|
100
|
|
192
|
|
264
|
if ( ref $_[0] ) { |
140
|
15
|
|
|
|
|
28
|
return @_[ 1, 0 ]; |
141
|
|
|
|
|
|
|
} |
142
|
|
|
|
|
|
|
else { |
143
|
177
|
100
|
|
|
|
336
|
return ( $_[0], ( defined $_[1] ? $_[1] : {} ) ); |
144
|
|
|
|
|
|
|
} |
145
|
|
|
|
|
|
|
} |
146
|
|
|
|
|
|
|
|
147
|
|
|
|
|
|
|
1; |
148
|
|
|
|
|
|
|
|
149
|
|
|
|
|
|
|
# ABSTRACT: Domain and host name validation |
150
|
|
|
|
|
|
|
|
151
|
|
|
|
|
|
|
__END__ |