|  line  | 
 stmt  | 
 bran  | 
 cond  | 
 sub  | 
 pod  | 
 time  | 
 code  | 
| 
1
 | 
  
 
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 package TUWF::Misc;  | 
| 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # Yeah, just put all miscellaneous functions in one module!  | 
| 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # Geez, talk about being sloppy...  | 
| 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
6
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
73642
 | 
 use strict;  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
12
 | 
    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
34
 | 
    | 
| 
7
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
5
 | 
 use warnings;  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1
 | 
    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
32
 | 
    | 
| 
8
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
5
 | 
 use Carp 'croak';  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1
 | 
    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
52
 | 
    | 
| 
9
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
5
 | 
 use Exporter 'import';  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
47
 | 
    | 
| 
10
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
12
 | 
 use Scalar::Util 'looks_like_number';  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
54
 | 
    | 
| 
11
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
437
 | 
 use TUWF::Validate;  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2150
 | 
    | 
| 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
13
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
14
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 our $VERSION = '1.5';  | 
| 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 our @EXPORT_OK = ('uri_escape', 'kv_validate');  | 
| 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
17
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub uri_escape {  | 
| 
19
 | 
  
0
  
 | 
 
 | 
 
 | 
  
0
  
 | 
  
1
  
 | 
0
 | 
   utf8::encode(local $_ = shift);  | 
| 
20
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   s/([^A-Za-z0-9._~-])/sprintf '%%%02X', ord $1/eg;  | 
| 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
21
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   return $_;  | 
| 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
23
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
24
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
25
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
26
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
27
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _template_validate_num {  | 
| 
28
 | 
13
 | 
 
 | 
 
 | 
  
13
  
 | 
 
 | 
32
 | 
   $_[0] *= 1; # Normalize to perl number  | 
| 
29
 | 
13
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
62
 | 
   return 0 if defined($_[1]{min}) && $_[0] < $_[1]{min};  | 
| 
30
 | 
9
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
48
 | 
   return 0 if defined($_[1]{max}) && $_[0] > $_[1]{max};  | 
| 
31
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
18
 | 
   return 1;  | 
| 
32
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
33
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
34
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
35
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 my %default_templates = (  | 
| 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # JSON number format, regex from http://stackoverflow.com/questions/13340717/json-numbers-regular-expression  | 
| 
37
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   num    => { func => \&_template_validate_num, regex => qr/^-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?$/, inherit => ['min','max'] },  | 
| 
38
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   int    => { func => \&_template_validate_num, regex => qr/^-?(?:0|[1-9]\d*)$/, inherit => ['min','max'] },  | 
| 
39
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   uint   => { func => \&_template_validate_num, regex => qr/^(?:0|[1-9]\d*)$/, inherit => ['min','max'] },  | 
| 
40
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   ascii  => { regex => qr/^[\x20-\x7E]*$/ },  | 
| 
41
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   email  => { regex => $TUWF::Validate::re_email, maxlength => 254 },  | 
| 
42
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   weburl => { regex => $TUWF::Validate::re_weburl, maxlength => 65536 }, # the maxlength is a bit arbitrary, but better than unlimited  | 
| 
43
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 );  | 
| 
44
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
45
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
46
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub kv_validate {  | 
| 
47
 | 
92
 | 
 
 | 
 
 | 
  
92
  
 | 
  
1
  
 | 
68459
 | 
   my($sources, $templates, $params) = @_;  | 
| 
48
 | 
92
 | 
 
 | 
 
 | 
 
 | 
 
 | 
614
 | 
   $templates = { %default_templates, %$templates };  | 
| 
49
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
50
 | 
92
 | 
 
 | 
 
 | 
 
 | 
 
 | 
208
 | 
   my @err;  | 
| 
51
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   my %ret;  | 
| 
52
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
53
 | 
92
 | 
 
 | 
 
 | 
 
 | 
 
 | 
165
 | 
   for my $f (@$params) {  | 
| 
54
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Inherit some options from templates.  | 
| 
55
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     !exists($f->{$_}) && _val_from_tpl($f, $_, $templates, $f)  | 
| 
56
 | 
92
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
352
 | 
       for(qw|required default rmwhitespace multi mincount maxcount|);  | 
| 
57
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
58
 | 
92
 | 
 
 | 
 
 | 
 
 | 
 
 | 
303
 | 
     my $src = (grep $f->{$_}, keys %$sources)[0];  | 
| 
59
 | 
92
 | 
 
 | 
 
 | 
 
 | 
 
 | 
249
 | 
     my @values = $sources->{$src}->($f->{$src});  | 
| 
60
 | 
92
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
1025
 | 
     @values = ($values[0]) if !$f->{multi};  | 
| 
61
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
62
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # check each value and add it to %ret  | 
| 
63
 | 
92
 | 
 
 | 
 
 | 
 
 | 
 
 | 
153
 | 
     for (@values) {  | 
| 
64
 | 
97
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
154
 | 
       my $errfield = _validate_early($_, $f) || _validate($_, $templates, $f);  | 
| 
65
 | 
97
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
335
 | 
       next if !$errfield || $errfield eq 'default';  | 
| 
66
 | 
47
 | 
 
 | 
 
 | 
 
 | 
 
 | 
131
 | 
       push @err, [ $f->{$src}, $errfield, $f->{$errfield} ];  | 
| 
67
 | 
47
 | 
 
 | 
 
 | 
 
 | 
 
 | 
83
 | 
       last;  | 
| 
68
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
69
 | 
92
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
260
 | 
     $ret{$f->{$src}} = $f->{multi} ? \@values : $values[0];  | 
| 
70
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
71
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # check mincount/maxcount  | 
| 
72
 | 
92
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
197
 | 
     push @err, [ $f->{$src}, 'mincount', $f->{mincount} ] if $f->{mincount} && @values < $f->{mincount};  | 
| 
73
 | 
92
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
234
 | 
     push @err, [ $f->{$src}, 'maxcount', $f->{maxcount} ] if $f->{maxcount} && @values > $f->{maxcount};  | 
| 
74
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
75
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
76
 | 
92
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
195
 | 
   $ret{_err} = \@err if @err;  | 
| 
77
 | 
92
 | 
 
 | 
 
 | 
 
 | 
 
 | 
398
 | 
   return \%ret;  | 
| 
78
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
79
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
80
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
81
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _val_from_tpl {  | 
| 
82
 | 
896
 | 
 
 | 
 
 | 
  
896
  
 | 
 
 | 
1283
 | 
   my($top_rules, $field, $tpls, $rules) = @_;  | 
| 
83
 | 
896
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
2019
 | 
   return if !$rules->{template};  | 
| 
84
 | 
379
 | 
 
 | 
 
 | 
 
 | 
 
 | 
539
 | 
   my $tpl = $tpls->{$rules->{template}};  | 
| 
85
 | 
379
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
571
 | 
   if(exists $tpl->{$field}) {  | 
| 
86
 | 
17
 | 
 
 | 
 
 | 
 
 | 
 
 | 
62
 | 
     $top_rules->{$field} = $tpl->{$field};  | 
| 
87
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   } else {  | 
| 
88
 | 
362
 | 
 
 | 
 
 | 
 
 | 
 
 | 
563
 | 
     _val_from_tpl($top_rules, $field, $tpls, $tpl);  | 
| 
89
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
90
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
91
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
92
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
93
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # Initial validation of a value. Same as _validate() below, but this one  | 
| 
94
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # validates options that need to be checked only once. (The checks in  | 
| 
95
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # _validate() may run several times when templates are used).  | 
| 
96
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _validate_early { # value, \%rules  | 
| 
97
 | 
97
 | 
 
 | 
 
 | 
  
97
  
 | 
 
 | 
160
 | 
   my($v, $r) = @_;  | 
| 
98
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
99
 | 
97
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
226
 | 
   $r->{required}++ if not exists $r->{required};  | 
| 
100
 | 
97
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
199
 | 
   $r->{rmwhitespace}++ if not exists $r->{rmwhitespace};  | 
| 
101
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
102
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # remove whitespace  | 
| 
103
 | 
97
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
340
 | 
   if($v && $r->{rmwhitespace}) {  | 
| 
104
 | 
75
 | 
 
 | 
 
 | 
 
 | 
 
 | 
170
 | 
     $_[0] =~ s/\r//g;  | 
| 
105
 | 
75
 | 
 
 | 
 
 | 
 
 | 
 
 | 
234
 | 
     $_[0] =~ s/^[\s\n]+//;  | 
| 
106
 | 
75
 | 
 
 | 
 
 | 
 
 | 
 
 | 
165
 | 
     $_[0] =~ s/[\s\n]+$//;  | 
| 
107
 | 
75
 | 
 
 | 
 
 | 
 
 | 
 
 | 
104
 | 
     $v = $_[0]  | 
| 
108
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
109
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
110
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # empty  | 
| 
111
 | 
97
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
374
 | 
   if(!defined($v) || length($v) < 1) {  | 
| 
112
 | 
9
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
32
 | 
     return 'required' if $r->{required};  | 
| 
113
 | 
3
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
8
 | 
     $_[0] = $r->{default} if exists $r->{default};  | 
| 
114
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9
 | 
     return 'default';  | 
| 
115
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
116
 | 
88
 | 
 
 | 
 
 | 
 
 | 
 
 | 
235
 | 
   return undef;  | 
| 
117
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
118
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
119
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
120
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # Internal function used by kv_validate, checks one value on the validation  | 
| 
121
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # rules, the name of the failed rule on error, undef otherwise  | 
| 
122
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _validate { # value, \%templates, \%rules  | 
| 
123
 | 
155
 | 
 
 | 
 
 | 
  
155
  
 | 
 
 | 
244
 | 
   my($v, $t, $r) = @_;  | 
| 
124
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
125
 | 
155
 | 
  
 50
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
443
 | 
   croak "Template $r->{template} not defined." if $r->{template} && !$t->{$r->{template}};  | 
| 
126
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
127
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # length  | 
| 
128
 | 
155
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
311
 | 
   return 'minlength' if $r->{minlength} && length $v < $r->{minlength};  | 
| 
129
 | 
153
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
338
 | 
   return 'maxlength' if $r->{maxlength} && length $v > $r->{maxlength};  | 
| 
130
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # enum  | 
| 
131
 | 
150
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
297
 | 
   return 'enum'      if $r->{enum} && !grep $_ eq $v, @{$r->{enum}};  | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
26
 | 
    | 
| 
132
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # regex  | 
| 
133
 | 
149
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
855
 | 
   return 'regex'     if $r->{regex} && (ref($r->{regex}) eq 'ARRAY' ? ($v !~ m/$r->{regex}[0]/) : ($v !~  m/$r->{regex}/));  | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
134
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # template  | 
| 
135
 | 
124
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
233
 | 
   if($r->{template}) {  | 
| 
136
 | 
67
 | 
 
 | 
 
 | 
 
 | 
 
 | 
121
 | 
     my $in = $t->{$r->{template}}{inherit};  | 
| 
137
 | 
67
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
152
 | 
     my %r = (($in ? (map exists($r->{$_}) ? ($_,$r->{$_}) : (), @$in) : ()), %{$t->{$r->{template}}});  | 
| 
 
 | 
67
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
217
 | 
    | 
| 
138
 | 
67
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
153
 | 
     return 'template'  if _validate($_[0], $t, \%r);  | 
| 
139
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
140
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # function  | 
| 
141
 | 
92
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
251
 | 
   return 'func'      if $r->{func} && (ref($r->{func}) eq 'ARRAY' ? !$r->{func}[0]->($_[0], $r) : !$r->{func}->($_[0], $r));  | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
142
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # passed validation  | 
| 
143
 | 
82
 | 
 
 | 
 
 | 
 
 | 
 
 | 
228
 | 
   return undef;  | 
| 
144
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
145
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
146
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
147
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
148
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
149
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub TUWF::Object::formValidate {  | 
| 
150
 | 
  
0
  
 | 
 
 | 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
   my($self, @fields) = @_;  | 
| 
151
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   return kv_validate(  | 
| 
152
 | 
  
0
  
 | 
 
 | 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
     { post   => sub { $self->reqPosts(shift)  },  | 
| 
153
 | 
  
0
  
 | 
 
 | 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
       get    => sub { $self->reqGets(shift)   },  | 
| 
154
 | 
  
0
  
 | 
 
 | 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
       param  => sub { $self->reqParams(shift) },  | 
| 
155
 | 
  
0
  
 | 
 
 | 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
       cookie => sub { $self->reqCookie(shift) },  | 
| 
156
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }, $self->{_TUWF}{validate_templates} || {},  | 
| 
157
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     \@fields  | 
| 
158
 | 
  
0
  
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
   );  | 
| 
159
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
160
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
161
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
162
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
163
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # A simple mail function, body and headers as arguments. Usage:  | 
| 
164
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #  $self->mail('body', header1 => 'value of header 1', ..);  | 
| 
165
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub TUWF::Object::mail {  | 
| 
166
 | 
  
0
  
 | 
 
 | 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
   my $self = shift;  | 
| 
167
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   my $body = shift;  | 
| 
168
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   my %hs = @_;  | 
| 
169
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
170
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   croak "No To: specified!\n" if !$hs{To};  | 
| 
171
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   croak "No Subject: specified!\n" if !$hs{Subject};  | 
| 
172
 | 
  
0
  
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
   $hs{'Content-Type'} ||= 'text/plain; charset=\'UTF-8\'';  | 
| 
173
 | 
  
0
  
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
   $hs{From} ||= $self->{_TUWF}{mail_from};  | 
| 
174
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   $body =~ s/\r?\n/\n/g;  | 
| 
175
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
176
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   my $mail = '';  | 
| 
177
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   foreach (keys %hs) {  | 
| 
178
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $hs{$_} =~ s/[\r\n]//g;  | 
| 
179
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $mail .= sprintf "%s: %s\n", $_, $hs{$_};  | 
| 
180
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
181
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   $mail .= sprintf "\n%s", $body;  | 
| 
182
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
183
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   if($self->{_TUWF}{mail_sendmail} eq 'log') {  | 
| 
 
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
184
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $self->log("tuwf->mail(): The following mail would have been sent:\n$mail");  | 
| 
185
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   } elsif(open(my $mailer, '|-:utf8', "$self->{_TUWF}{mail_sendmail} -t -f '$hs{From}'")) {  | 
| 
186
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     print $mailer $mail;  | 
| 
187
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     croak "Error running sendmail ($!)"  | 
| 
188
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       if !close($mailer);  | 
| 
189
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   } else {  | 
| 
190
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     croak "Error opening sendail ($!)";  | 
| 
191
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
192
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
193
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
194
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
195
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub TUWF::Object::compile {  | 
| 
196
 | 
  
0
  
 | 
 
 | 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
   TUWF::Validate::compile($_[0]{_TUWF}{custom_validations}, $_[1]);  | 
| 
197
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
198
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
199
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
200
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _compile {  | 
| 
201
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
   ref $_[0] eq 'TUWF::Validate' ? $_[0] : $TUWF::OBJ->compile($_[0]);  | 
| 
202
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
203
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
204
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
205
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub TUWF::Object::validate {  | 
| 
206
 | 
  
0
  
 | 
 
 | 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
   my $self = shift;  | 
| 
207
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   my $what = shift;  | 
| 
208
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
209
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   return _compile($_[0])->validate($self->reqJSON) if $what eq 'json';  | 
| 
210
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
211
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # 'param' is special, and not really encouraged. Create a new hash based on  | 
| 
212
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # reqParam() and cache the result.  | 
| 
213
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   $self->{_TUWF}{Req}{PARAM} ||= {  | 
| 
214
 | 
  
0
  
 | 
  
  0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
     map { my @v = $self->reqParams($_); +($_, @v > 1 ? \@v : $v[0]) } $self->reqParams()  | 
| 
 
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
215
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   } if $what eq 'param';  | 
| 
216
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
217
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   my $source =  | 
| 
218
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $what eq 'get'   ? $self->{_TUWF}{Req}{GET} :  | 
| 
219
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $what eq 'post'  ? $self->{_TUWF}{Req}{POST} :  | 
| 
220
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $what eq 'param' ? $self->{_TUWF}{Req}{PARAM}  | 
| 
221
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                      : croak "Invalid source type '$what'";  | 
| 
 
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
222
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
223
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # Multi-value, schema hash or object  | 
| 
224
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   return _compile($_[0])->validate($source) if @_ == 1;  | 
| 
225
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
226
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # Single value  | 
| 
227
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   return _compile($_[1])->validate($source->{$_[0]}) if @_ == 2;  | 
| 
228
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
229
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # Multi-value, separate params  | 
| 
230
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   _compile({ type => 'hash', keys => { @_ } })->validate($source);  | 
| 
231
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
232
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
233
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
234
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # Internal function used by other TUWF modules to find an appropriate JSON  | 
| 
235
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # module. Kinda like JSON::MaybeXS, but without an extra dependency.  | 
| 
236
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _JSON {  | 
| 
237
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
     return 'JSON::XS'         if $INC{'JSON/XS.pm'};  | 
| 
238
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     return 'Cpanel::JSON::XS' if $INC{'Cpanel/JSON/XS.pm'};  | 
| 
239
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     return 'JSON::PP'         if $INC{'JSON/PP.pm'};  | 
| 
240
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     return 'JSON::XS'         if eval { require JSON::XS; 1 };  | 
| 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
241
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     return 'Cpanel::JSON::XS' if eval { require Cpanel::JSON::XS; 1 };  | 
| 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
242
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     die "Unable to load a suitable JSON module: $@" if !eval { require JSON::PP; 1 };  | 
| 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
243
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     'JSON::PP'  | 
| 
244
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
245
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
246
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 1;  |