File Coverage

blib/lib/Data/Validate.pm
Criterion Covered Total %
statement 82 82 100.0
branch 63 66 95.4
condition 4 6 66.6
subroutine 14 14 100.0
pod 7 7 100.0
total 170 175 97.1


line stmt bran cond sub pod time code
1             package Data::Validate;
2              
3 13     13   400212 use strict;
  13         33  
  13         656  
4 13     13   75 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
  13         30  
  13         1306  
5              
6             require Exporter;
7 13     13   13937 use AutoLoader 'AUTOLOAD';
  13         36966  
  13         83  
8              
9 13     13   14281 use POSIX;
  13         136279  
  13         103  
10 13     13   52012 use Scalar::Util qw(looks_like_number);
  13         28  
  13         1625  
11 13     13   32063 use Math::BigInt;
  13         493421  
  13         89  
12 13     13   293638 use Config;
  13         33  
  13         2040  
13              
14             @ISA = qw(Exporter);
15              
16              
17              
18             # no functions are exported by default. See EXPORT_OK
19             @EXPORT = qw();
20              
21             @EXPORT_OK = qw(
22             is_integer
23             is_numeric
24             is_hex
25             is_oct
26             is_between
27             is_greater_than
28             is_less_than
29             is_equal_to
30             is_even
31             is_odd
32             is_alphanumeric
33             is_printable
34             length_is_between
35             );
36              
37             %EXPORT_TAGS = (
38             math => [qw(is_integer is_numeric is_hex is_oct is_between is_greater_than is_less_than is_equal_to is_even is_odd)],
39             string => [qw(is_equal_to is_alphanumeric is_printable length_is_between)],
40             );
41              
42             $VERSION = '0.09';
43              
44              
45             # No preloads
46              
47             1;
48             __END__
49            
50             =head1 NAME
51            
52             Data::Validate - common data validation methods
53            
54             =head1 SYNOPSIS
55            
56             use Data::Validate qw(:math);
57            
58             if(defined(is_integer($suspect))){
59             print "Looks like an integer\n";
60             }
61            
62             my $name = is_alphanumeric($suspect);
63             if(defined($name)){
64             print "$name is alphanumeric, and has been untainted\n";
65             } else {
66             print "$suspect was not alphanumeric"
67             }
68            
69             # or as an object
70             my $v = Data::Validate->new();
71            
72             die "'foo' is not an integer" unless defined($v->is_integer('foo'));
73            
74             =head1 DESCRIPTION
75            
76             This module collects common validation routines to make input validation,
77             and untainting easier and more readable. Most of the functions are not much
78             shorter than their direct perl equivalent (and are much longer in some cases),
79             but their names make it clear what you're trying to test for.
80            
81             Almost all functions return an untainted value if the test passes, and undef if
82             it fails. This means that you should always check for a defined status explicitly.
83             Don't assume the return will be true. (e.g. is_integer(0))
84            
85             The value to test is always the first (and often only) argument.
86            
87             =head1 FUNCTIONS
88            
89             =over 4
90            
91             =cut
92            
93             # -------------------------------------------------------------------------------
94            
95             =pod
96            
97             =item B<new> - constructor for OO usage
98            
99             new();
100            
101             =over 4
102            
103             =item I<Description>
104            
105             Returns a Data::Validator object. This lets you access all the validator function
106             calls as methods without importing them into your namespace or using the clumsy
107             Data::Validate::function_name() format.
108            
109             =item I<Arguments>
110            
111             None
112            
113             =item I<Returns>
114            
115             Returns a Data::Validate object
116            
117             =back
118            
119             =cut
120            
121             sub new{
122 13     13 1 431 my $class = shift;
123            
124 13         64 return bless {}, $class;
125             }
126            
127             # -------------------------------------------------------------------------------
128            
129             =pod
130            
131             =item B<is_integer> - is the value an integer?
132            
133             is_integer($value);
134            
135             =over 4
136            
137             =item I<Description>
138            
139             Returns the untainted number if the test value is an integer, or can be cast to
140             one without a loss of precision. (i.e. 1.0 is considered an integer, but 1.0001 is not.)
141            
142             =item I<Arguments>
143            
144             =over 4
145            
146             =item $value
147            
148             The potential integer to test.
149            
150             =back
151            
152             =item I<Returns>
153            
154             Returns the untainted integer on success, undef on failure. Note that the return
155             can be 0, so always check with defined()
156            
157             =item I<Notes, Exceptions, & Bugs>
158            
159             Number translation is done by POSIX casting tools (strtol).
160            
161             =back
162            
163             =cut
164            
165             sub is_integer{
166 32 100   39 1 202 my $self = shift if ref($_[0]);
167 32         57 my $value = shift;
168            
169 31 100       81 return unless defined($value);
170 29 100       569 return unless defined(is_numeric($value)); # for efficiency
171            
172             # see if we can parse it to an number without loss
173 26         220 my($int, $leftover) = POSIX::strtod($value);
174            
175 26 100       77 return if $leftover;
176            
177             # we're having issues testing very large integers. Math::BigInt
178             # can do this for us, but defeats the purpose of being
179             # lightweight. So, we're going to try a huristic method to choose
180             # how to test for integernesss
181 20 100 66     3246 if(!$Config{uselongdouble} && length($int) > 10){
182 2         14 my $i = Math::BigInt->new($value);
183 2 100       210 return unless $i->is_int();
184            
185             # untaint
186 2         70 ($int) = $i->bstr() =~ /(.+)/;
187 2         121 return $int;
188             }
189            
190            
191             # shorter integer must be identical to the raw cast
192 18 50       10905 return unless (($int + 0) == ($value + 0));
193            
194             # could still be a float at this point.
195 18 100       121 return if $value =~ /[^0-9\-]/;
196            
197             # looks like it really is an integer. Untaint it and return
198 15         59 ($value) = $int =~ /([\d\-]+)/;
199            
200 15         341 return $value + 0;
201             }
202            
203            
204             # -------------------------------------------------------------------------------
205            
206             =pod
207            
208             =item B<is_numeric> - is the value numeric?
209            
210             is_numeric($value);
211            
212             =over 4
213            
214             =item I<Description>
215            
216             Returns the untainted number if the test value is numeric according to
217             Perl's own internal rules. (actually a wrapper on Scalar::Util::looks_like_number)
218            
219             =item I<Arguments>
220            
221             =over 4
222            
223             =item $value
224            
225             The potential number to test.
226            
227             =back
228            
229             =item I<Returns>
230            
231             Returns the untainted number on success, undef on failure. Note that the return
232             can be 0, so always check with defined()
233            
234             =item I<Notes, Exceptions, & Bugs>
235            
236             Number translation is done by POSIX casting tools (strtol).
237            
238             =back
239            
240             =cut
241            
242             sub is_numeric{
243 82 100   82 1 708 my $self = shift if ref($_[0]);
244 82         110 my $value = shift;
245            
246 82 50       242 return unless defined($value);
247            
248 82 100       571 return unless looks_like_number($value);
249            
250             # looks like it really is a number. Untaint it and return
251 71         359 ($value) = $value =~ /([\d\.\-+e]+)/;
252            
253 71         2274 return $value + 0;
254             }
255            
256            
257             # -------------------------------------------------------------------------------
258            
259             =pod
260            
261             =item B<is_hex> - is the value a hex number?
262            
263             is_hex($value);
264            
265             =over 4
266            
267             =item I<Description>
268            
269             Returns the untainted number if the test value is a hex number.
270            
271             =item I<Arguments>
272            
273             =over 4
274            
275             =item $value
276            
277             The potential number to test.
278            
279             =back
280            
281             =item I<Returns>
282            
283             Returns the untainted number on success, undef on failure. Note that the return
284             can be 0, so always check with defined()
285            
286             =item I<Notes, Exceptions, & Bugs>
287            
288             None
289            
290             =back
291            
292             =cut
293            
294             sub is_hex {
295             my $self = shift if ref($_[0]);
296             my $value = shift;
297            
298             return unless defined $value;
299            
300             return if $value =~ /[^0-9a-f]/i;
301             $value = lc($value);
302            
303             my $int = hex($value);
304             return unless (defined $int);
305             my $hex = sprintf "%x", $int;
306             return $hex if ($hex eq $value);
307            
308             # handle zero stripping
309             if (my ($z) = $value =~ /^(0+)/) {
310             return "$z$hex" if ("$z$hex" eq $value);
311             }
312            
313             return;
314             }
315            
316             # -------------------------------------------------------------------------------
317            
318             =pod
319            
320             =item B<is_oct> - is the value an octal number?
321            
322             is_oct($value);
323            
324             =over 4
325            
326             =item I<Description>
327            
328             Returns the untainted number if the test value is a octal number.
329            
330             =item I<Arguments>
331            
332             =over 4
333            
334             =item $value
335            
336             The potential number to test.
337            
338             =back
339            
340             =item I<Returns>
341            
342             Returns the untainted number on success, undef on failure. Note that the return
343             can be 0, so always check with defined()
344            
345             =item I<Notes, Exceptions, & Bugs>
346            
347             None
348            
349             =back
350            
351             =cut
352            
353             sub is_oct {
354             my $self = shift if ref($_[0]);
355             my $value = shift;
356            
357             return unless defined $value;
358            
359             return if $value =~ /[^0-7]/;
360            
361             my $int = oct($value);
362             return unless (defined $int);
363             my $oct = sprintf "%o", $int;
364             return $oct if ($oct eq $value);
365            
366             # handle zero stripping
367             if (my ($z) = $value =~ /^(0+)/) {
368             return "$z$oct" if ("$z$oct" eq $value);
369             }
370            
371             return;
372             }
373            
374            
375             # -------------------------------------------------------------------------------
376            
377             =pod
378            
379             =item B<is_between> - is the value between two numbers?
380            
381             is_between($value, $min, $max);
382            
383             =over 4
384            
385             =item I<Description>
386            
387             Returns the untainted number if the test value is numeric, and falls between
388             $min and $max inclusive. Note that either $min or $max can be undef, which
389             means 'unlimited'. i.e. is_between($val, 0, undef) would pass for any number
390             zero or larger.
391            
392             =item I<Arguments>
393            
394             =over 4
395            
396             =item $value
397            
398             The potential number to test.
399            
400             =item $min
401            
402             The minimum valid value. Unlimited if set to undef
403            
404             =item $max
405            
406             The maximum valid value. Unlimited if set to undef
407            
408             =back
409            
410             =item I<Returns>
411            
412             Returns the untainted number on success, undef on failure. Note that the return
413             can be 0, so always check with defined()
414            
415            
416             =back
417            
418             =cut
419            
420             sub is_between{
421 31 100   31 1 340 my $self = shift if ref($_[0]);
422 31         117 my $value = shift;
423 31         230 my $min = shift;
424 30         359 my $max = shift;
425            
426             # must be a number
427 27         287 my $untainted = is_numeric($value);
428 25 100       76 return unless defined($untainted);
429            
430             # issues with very large numbers. Fall over to using
431             # arbitrary precisions math.
432 22 100       74 if(length($value) > 10){
433            
434 15         138 my $i = Math::BigInt->new($value);
435            
436             # minimum bound
437 8 100       229 if(defined($min)){
438 8         12 $min = Math::BigInt->new($min);
439 8 100       263 return unless $i >= $min;
440             }
441            
442             # maximum bound
443 16 100       269 if(defined($max)){
444 15         32 $max = Math::BigInt->new($max);
445 15 100       335 return unless $i <= $max;
446             }
447            
448             # untaint
449 11         278 ($value) = $i->bstr() =~ /(.+)/;
450 17         205 return $value;
451             }
452            
453            
454             # minimum bound
455 23 100       62 if(defined($min)){
456 19 100       60 return unless $value >= $min;
457             }
458            
459             # maximum bound
460 24 100       228 if(defined($max)){
461 20 100       45 return unless $value <= $max;
462             }
463            
464 19         52 return $untainted;
465             }
466            
467            
468             # -------------------------------------------------------------------------------
469            
470             =pod
471            
472             =item B<is_greater_than> - is the value greater than a threshold?
473            
474             is_greater_than($value, $threshold);
475            
476             =over 4
477            
478             =item I<Description>
479            
480             Returns the untainted number if the test value is numeric, and is greater than
481             $threshold. (not inclusive)
482            
483             =item I<Arguments>
484            
485             =over 4
486            
487             =item $value
488            
489             The potential number to test.
490            
491             =item $threshold
492            
493             The minimum value (non-inclusive)
494            
495             =back
496            
497             =item I<Returns>
498            
499             Returns the untainted number on success, undef on failure. Note that the return
500             can be 0, so always check with defined()
501            
502            
503             =back
504            
505             =cut
506            
507             sub is_greater_than{
508             my $self = shift if ref($_[0]);
509             my $value = shift;
510             my $threshold = shift;
511            
512             # must be a number
513             my $untainted = is_numeric($value);
514             return unless defined($untainted);
515            
516             # threshold must be defined
517             return unless defined $threshold;
518            
519             return unless $value > $threshold;
520            
521             return $untainted;
522             }
523            
524             # -------------------------------------------------------------------------------
525            
526             =pod
527            
528             =item B<is_less_than> - is the value less than a threshold?
529            
530             is_less_than($value, $threshold);
531            
532             =over 4
533            
534             =item I<Description>
535            
536             Returns the untainted number if the test value is numeric, and is less than
537             $threshold. (not inclusive)
538            
539             =item I<Arguments>
540            
541             =over 4
542            
543             =item $value
544            
545             The potential number to test.
546            
547             =item $threshold
548            
549             The maximum value (non-inclusive)
550            
551             =back
552            
553             =item I<Returns>
554            
555             Returns the untainted number on success, undef on failure. Note that the return
556             can be 0, so always check with defined()
557            
558            
559             =back
560            
561             =cut
562            
563             sub is_less_than{
564             my $self = shift if ref($_[0]);
565             my $value = shift;
566             my $threshold = shift;
567            
568             # must be a number
569             my $untainted = is_numeric($value);
570             return unless defined($untainted);
571            
572             # threshold must be defined
573             return unless defined $threshold;
574            
575             return unless $value < $threshold;
576            
577             return $untainted;
578             }
579            
580            
581             # -------------------------------------------------------------------------------
582            
583             =pod
584            
585             =item B<is_equal_to> - do a string/number neutral ==
586            
587             is_equal_to($value, $target);
588            
589             =over 4
590            
591             =item I<Description>
592            
593             Returns the target if $value is equal to it. Does a math comparison if
594             both $value and $target are numeric, or a string comparison otherwise.
595             Both the $value and $target must be defined to get a true return. (i.e.
596             undef != undef)
597            
598             =item I<Arguments>
599            
600             =over 4
601            
602             =item $value
603            
604             The value to test.
605            
606             =item $target
607            
608             The value to test against
609            
610             =back
611            
612             =item I<Returns>
613            
614             Unlike most validator routines, this one does not necessarily untaint its return value,
615             it just returns $target. This has the effect of untainting if the target is a constant or
616             other clean value. (i.e. is_equal_to($bar, 'foo')). Note that the return
617             can be 0, so always check with defined()
618            
619            
620             =back
621            
622             =cut
623            
624             sub is_equal_to{
625 22 100   22 1 340 my $self = shift if ref($_[0]);
626 20         50 my $value = shift;
627 20         73 my $target = shift;
628            
629             # value and target must be defined
630 12 100       34 return unless defined $value;
631 11 100       29 return unless defined $target;
632            
633 18 100 66     331 if(defined(is_numeric($value)) && defined(is_numeric($target))){
634 16 100       43 return $target if $value == $target;
635             } else {
636             # string comparison
637 12 100       29 return $target if $value eq $target;
638             }
639            
640 14         32 return;
641             }
642            
643             # -------------------------------------------------------------------------------
644            
645             =pod
646            
647             =item B<is_even> - is a number even?
648            
649             is_even($value);
650            
651             =over 4
652            
653             =item I<Description>
654            
655             Returns the untainted $value if it's numeric, an integer, and even.
656            
657             =item I<Arguments>
658            
659             =over 4
660            
661             =item $value
662            
663             The value to test.
664            
665             =back
666            
667             =item I<Returns>
668            
669             Returns $value (untainted). Note that the return can be 0, so always
670             check with defined().
671            
672            
673             =back
674            
675             =cut
676            
677             sub is_even{
678       10 1   my $self = shift if ref($_[0]);
679             my $value = shift;
680            
681             return unless defined(is_numeric($value));
682             my $untainted = is_integer($value);
683             return unless defined($untainted);
684            
685             return $untainted unless $value % 2;
686            
687             return;
688             }
689            
690             # -------------------------------------------------------------------------------
691            
692             =pod
693            
694             =item B<is_odd> - is a number odd?
695            
696             is_odd($value);
697            
698             =over 4
699            
700             =item I<Description>
701            
702             Returns the untainted $value if it's numeric, an integer, and odd.
703            
704             =item I<Arguments>
705            
706             =over 4
707            
708             =item $value
709            
710             The value to test.
711            
712             =back
713            
714             =item I<Returns>
715            
716             Returns $value (untainted). Note that the return can be 0, so always
717             check with defined().
718            
719             =back
720            
721             =cut
722            
723             sub is_odd{
724             my $self = shift if ref($_[0]);
725             my $value = shift;
726            
727             return unless defined(is_numeric($value));
728             my $untainted = is_integer($value);
729             return unless defined($untainted);
730            
731             return $untainted if $value % 2;
732            
733             return;
734             }
735            
736            
737            
738             # -------------------------------------------------------------------------------
739            
740             =pod
741            
742             =item B<is_alphanumeric> - does it only contain letters and numbers?
743            
744             is_alphanumeric($value);
745            
746             =over 4
747            
748             =item I<Description>
749            
750             Returns the untainted $value if it is defined and only contains letters (upper
751             or lower case) and numbers. Also allows an empty string - ''.
752            
753             =item I<Arguments>
754            
755             =over 4
756            
757             =item $value
758            
759             The value to test.
760            
761             =back
762            
763             =item I<Returns>
764            
765             Returns $value (untainted). Note that the return can be 0, so always
766             check with defined().
767            
768             =back
769            
770             =cut
771            
772             sub is_alphanumeric{
773 10 100   10 1 99 my $self = shift if ref($_[0]);
774 10         14 my $value = shift;
775            
776 10 50       24 return unless defined($value);
777 10 100       31 return '' if $value eq ''; # allow for empty string
778            
779 8         23 my($untainted) = $value =~ /([a-z0-9]+)/i;
780            
781 8 100       31 return unless defined($untainted);
782 4 100       12 return unless $untainted eq $value;
783            
784 3         16 return $untainted;
785            
786             }
787            
788            
789             # -------------------------------------------------------------------------------
790            
791             =pod
792            
793             =item B<is_printable> - does it only contain printable characters?
794            
795             is_alphanumeric($value);
796            
797             =over 4
798            
799             =item I<Description>
800            
801             Returns the untainted $value if it is defined and only contains printable characters
802             as defined by the composite POSIX character class [[:print:][:space:]]. Also allows an empty string - ''.
803            
804             =item I<Arguments>
805            
806             =over 4
807            
808             =item $value
809            
810             The value to test.
811            
812             =back
813            
814             =item I<Returns>
815            
816             Returns $value (untainted). Note that the return can be 0, so always
817             check with defined().
818            
819             =back
820            
821             =cut
822            
823             sub is_printable{
824             my $self = shift if ref($_[0]);
825             my $value = shift;
826            
827             return unless defined($value);
828             return '' if $value eq ''; # allow for empty string
829            
830             my($untainted) = $value =~ /([[:print:][:space:]]+)/i;
831            
832             return unless defined($untainted);
833             return unless $untainted eq $value;
834            
835             return $untainted;
836            
837             }
838            
839            
840             # -------------------------------------------------------------------------------
841            
842             =pod
843            
844             =item B<length_is_between> - is the string length between two limits?
845            
846             length_is_between($value, $min, $max);
847            
848             =over 4
849            
850             =item I<Description>
851            
852             Returns $value if it is defined and its length
853             is between $min and $max inclusive. Note that this function does not
854             untaint the value.
855            
856             If either $min or $max are undefined they are treated as no-limit.
857            
858             =item I<Arguments>
859            
860             =over 4
861            
862             =item $value
863            
864             The value to test.
865            
866             =item $min
867            
868             The minimum length of the string (inclusive).
869            
870             =item $max
871            
872             The maximum length of the string (inclusive).
873            
874             =back
875            
876             =item I<Returns>
877            
878             Returns $value. Note that the return can be 0, so always check with
879             defined(). The value is not automatically untainted.
880            
881             =back
882            
883             =cut
884            
885             sub length_is_between{
886             my $self = shift if ref($_[0]);
887             my $value = shift;
888             my $min = shift;
889             my $max = shift;
890            
891             return unless defined($value);
892            
893             if(defined($min)){
894             return unless length($value) >= $min;
895             }
896            
897             if(defined($max)){
898             return unless length($value) <= $max;
899             }
900            
901             return $value;
902            
903             }
904            
905            
906             =pod
907            
908             =back
909            
910             =head1 AUTHOR
911            
912             Richard Sonnen <F<sonnen@richardsonnen.com>>.
913            
914             =head1 COPYRIGHT
915            
916             Copyright (c) 2004 Richard Sonnen. All rights reserved.
917            
918             This program is free software; you can redistribute it and/or modify
919             it under the same terms as Perl itself.
920            
921             =cut
922