File Coverage

blib/lib/Apache/Voodoo/Validate/varchar.pm
Criterion Covered Total %
statement 42 46 91.3
branch 27 30 90.0
condition 10 12 83.3
subroutine 7 7 100.0
pod 0 2 0.0
total 86 97 88.6


line stmt bran cond sub pod time code
1             package Apache::Voodoo::Validate::varchar;
2              
3             $VERSION = "3.0200";
4              
5 2     2   14 use strict;
  2         4  
  2         72  
6 2     2   11 use warnings;
  2         3  
  2         67  
7              
8 2     2   12 use base("Apache::Voodoo::Validate::Plugin");
  2         4  
  2         399  
9              
10 2     2   2157 use Email::Valid;
  2         287404  
  2         1920  
11              
12             sub config {
13 11     11 0 19 my ($self,$c) = @_;
14              
15 11         11 my @e;
16 11 100       22 if (defined($c->{length})) {
17 10 50       37 if ($c->{length} =~ /^\d+$/) {
18 10         20 $self->{length} = $c->{length};
19             }
20             else {
21 0         0 push(@e,"'length' must be positive integer");
22             }
23             }
24             else {
25 1         5 $self->{length} = 0;
26             }
27              
28 11 100       31 if (defined($c->{valid})) {
29 5 100       21 if ($c->{valid} =~ /^(url|email)$/ ) {
    50          
30 4         9 $self->{'valid'} = $c->{valid};
31             }
32             elsif (ref($c->{valid}) ne "CODE") {
33 0         0 push(@e,"valid must be either 'email','url', or a subroutine reference");
34             }
35             }
36              
37 11 100       24 if (defined($c->{regexp})) {
38 2         4 $self->{regexp} = $c->{regexp};
39             }
40              
41 11         29 return @e;
42             }
43              
44             sub valid {
45 39     39 0 71 my ($self,$v) = @_;
46              
47 39         43 my $e;
48 39 100 100     407 if ($self->{'length'} > 0 && length($v) > $self->{'length'}) {
    100 100        
    100 66        
    100          
49 9         14 $e = 'BIG';
50             }
51             elsif (defined($self->{'valid'}) && $self->{'valid'} eq 'email') {
52             # Net::DNS pollutes the value of $_ with the IP of the DNS server that responsed to the lookup
53             # request. It's localized to keep Net::DNS out of my pool.
54 6         11 local $_;
55              
56 6         10 my $addr;
57 6         10 eval {
58 6         60 $addr = Email::Valid->address('-address' => $v,
59             '-mxcheck' => 1,
60             '-fqdn' => 1 );
61             };
62 6 50       76479 if ($@) {
    100          
63 0         0 Apache::Voodoo::Exception::Runtime->throw("Email::Valid produced an exception: $@");
64 0         0 $e = 'BAD';
65             }
66             elsif(!defined($addr)) {
67 2         6 $e = 'BAD';
68             }
69             }
70             elsif (defined($self->{'valid'}) && $self->{'valid'} eq 'url') {
71 5 100 66     25 if (length($v) && _valid_url($v) == 0) {
72 2         4 $e = 'BAD';
73             }
74             }
75             elsif (defined($self->{'regexp'})) {
76 5         13 my $re = $self->{'regexp'};
77 5 100       57 unless ($v =~ /$re/) {
78 2         4 $e = 'BAD';
79             }
80             }
81              
82 39         169 return $v,$e;
83             }
84              
85              
86             #
87             # I saw this code fragment somewhere ages ago, I can't remember where.
88             # So, I can't attribute it to the proper author. sorry!
89             #
90             # I've stripped out everthing not pertaining to HTTP URLs. That
91             # was the part I really needed.
92             #
93              
94             # Be paranoid about using grouping!
95             my $digits = '(?:\d+)';
96             my $dot = '\.';
97             my $qm = '\?';
98             my $hex = '[a-fA-F\d]';
99             my $alpha = '[a-zA-Z]'; # No, no locale.
100             my $alphas = "(?:${alpha}+)";
101             my $alphanum = '[a-zA-Z\d]'; # Letter or digit.
102             my $xalphanum = "(?:${alphanum}|%(?:3\\d|[46]$hex|[57][Aa\\d]))";
103             # Letter or digit, or hex escaped letter/digit.
104             my $alphanums = "(?:${alphanum}+)";
105             my $escape = "(?:%$hex\{2})";
106             my $safe = '[$\-_.+]';
107             my $extra = "[!*'(),]";
108             my $reserved = '[;/?:@&=]';
109             my $uchar = "(?:${alphanum}|${safe}|${extra}|${escape})";
110             $uchar =~ s/\Q]|[\E//g; # Make string smaller, and speed up regex.
111              
112             # URL schemeparts for ip based protocols:
113             my $user = "(?:(?:${uchar}|[;?&=])*)";
114             my $password = "(?:(?:${uchar}|[;?&=])*)";
115             my $hostnumber = "(?:${digits}(?:${dot}${digits}){3})";
116             my $toplabel = "(?:${alpha}(?:(?:${alphanum}|-)*${alphanum})?)";
117             my $domainlabel = "(?:${alphanum}(?:(?:${alphanum}|-)*${alphanum})?)";
118             my $hostname = "(?:(?:${domainlabel}${dot})*${toplabel})";
119             my $host = "(?:${hostname}|${hostnumber})";
120             my $hostport = "(?:${host}(?::${digits})?)";
121             my $login = "(?:(?:${user}(?::${password})?\@)?${hostport})";
122              
123             # The predefined schemes:
124              
125             ## FTP (see also RFC959)
126             #my $fsegment = "(?:(?:${uchar}|[?:\@&=])*)";
127             #my $fpath = "(?:${fsegment}(?:/${fsegment})*)";
128             #my $ftpurl = "(?:ftp://${login}(?:/${fpath}(?:;type=[AIDaid])?)?)";
129              
130              
131             # HTTP
132             my $hsegment = "(?:(?:${uchar}|[;:\@&=])*)";
133             my $search = "(?:(?:${uchar}|[;:\@&=])*)";
134             my $hpath = "(?:${hsegment}(?:/${hsegment})*)";
135             my $httpurl = "(?:http(s)?://${hostport}(?:/${hpath}(?:${qm}${search})?)?)";
136              
137             sub _valid_url {
138 5     5   11 my $test = shift;
139              
140 5 100       333 return ($test =~ /^$httpurl$/o)?1:0;
141             }
142              
143             1;
144              
145             ################################################################################
146             # Copyright (c) 2005-2010 Steven Edwards (maverick@smurfbane.org).
147             # All rights reserved.
148             #
149             # You may use and distribute Apache::Voodoo under the terms described in the
150             # LICENSE file include in this package. The summary is it's a legalese version
151             # of the Artistic License :)
152             #
153             ################################################################################