| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package Respite::Validate; |
|
2
|
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
# Respite::Validate - lighter weight port of CGI::Ex::Validate |
|
4
|
|
|
|
|
|
|
|
|
5
|
3
|
|
|
3
|
|
372587
|
use strict; |
|
|
3
|
|
|
|
|
5
|
|
|
|
3
|
|
|
|
|
109
|
|
|
6
|
3
|
|
|
3
|
|
12
|
use warnings; |
|
|
3
|
|
|
|
|
4
|
|
|
|
3
|
|
|
|
|
195
|
|
|
7
|
3
|
|
|
3
|
|
347
|
use Throw qw(throw); |
|
|
3
|
|
|
|
|
1697
|
|
|
|
3
|
|
|
|
|
17
|
|
|
8
|
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
sub new { |
|
10
|
254
|
|
|
254
|
0
|
118550
|
my ($class, $args) = @_; |
|
11
|
254
|
|
50
|
|
|
2034
|
bless $args || {}, $class; |
|
12
|
|
|
|
|
|
|
} |
|
13
|
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
sub validate { |
|
15
|
254
|
100
|
|
254
|
0
|
980
|
my ($self, $form, $val_hash) = (@_ == 3) ? @_ : (__PACKAGE__->new(), @_); |
|
16
|
254
|
50
|
|
|
|
807
|
throw "args must be a hashref", {ref => ref($form)} if ref $form ne 'HASH'; |
|
17
|
254
|
|
|
|
|
654
|
my ($fields, $ARGS) = $self->get_ordered_fields($val_hash); |
|
18
|
254
|
50
|
|
|
|
600
|
return if ! @$fields; |
|
19
|
254
|
100
|
100
|
|
|
624
|
return if $ARGS->{'validate_if'} && ! $self->check_conditional($form, $ARGS->{'validate_if'}); |
|
20
|
|
|
|
|
|
|
|
|
21
|
250
|
|
|
|
|
652
|
$self->{'was_checked'} = {}; |
|
22
|
250
|
|
|
|
|
526
|
$self->{'was_valid'} = {}; |
|
23
|
250
|
|
|
|
|
429
|
$self->{'had_error'} = {}; |
|
24
|
250
|
|
|
|
|
380
|
my $found = 1; |
|
25
|
250
|
|
|
|
|
589
|
my @errors; |
|
26
|
|
|
|
|
|
|
my $hold_error; # hold the error for a moment - to allow for an "OR" operation |
|
27
|
250
|
|
|
|
|
0
|
my %checked; |
|
28
|
250
|
|
|
|
|
666
|
foreach (my $i = 0; $i < @$fields; $i++) { |
|
29
|
268
|
|
|
|
|
451
|
my $ref = $fields->[$i]; |
|
30
|
268
|
50
|
33
|
|
|
712
|
if (! ref($ref) && $ref eq 'OR') { |
|
31
|
0
|
0
|
|
|
|
0
|
$i++ if $found; # if found skip the OR altogether |
|
32
|
0
|
|
|
|
|
0
|
$found = 1; # reset |
|
33
|
0
|
|
|
|
|
0
|
next; |
|
34
|
|
|
|
|
|
|
} |
|
35
|
268
|
|
|
|
|
429
|
$found = 1; |
|
36
|
268
|
|
33
|
|
|
695
|
my $key = $ref->{'field'} || throw "Missing field key during normal validation"; |
|
37
|
|
|
|
|
|
|
|
|
38
|
|
|
|
|
|
|
# allow for field names that contain regular expressions |
|
39
|
268
|
|
|
|
|
383
|
my @keys; |
|
40
|
268
|
100
|
|
|
|
797
|
if ($key =~ m/^(!\s*|)m([^\s\w])(.*)\2([eigsmx]*)$/s) { |
|
41
|
9
|
|
|
|
|
53
|
my ($not, $pat, $opt) = ($1, $3, $4); |
|
42
|
9
|
|
|
|
|
16
|
$opt =~ tr/g//d; |
|
43
|
9
|
50
|
|
|
|
23
|
throw "The e option cannot be used on validation keys on field $key" if $opt =~ /e/; |
|
44
|
9
|
|
|
|
|
27
|
foreach my $_key (sort keys %$form) { |
|
45
|
15
|
100
|
33
|
|
|
168
|
next if ($not && $_key =~ m/(?$opt:$pat)/) || (! $not && $_key !~ m/(?$opt:$pat)/); |
|
|
|
|
66
|
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
46
|
9
|
|
|
|
|
50
|
push @keys, [$_key, [undef, $1, $2, $3, $4, $5]]; |
|
47
|
|
|
|
|
|
|
} |
|
48
|
|
|
|
|
|
|
} else { |
|
49
|
259
|
|
|
|
|
690
|
@keys = ([$key]); |
|
50
|
|
|
|
|
|
|
} |
|
51
|
|
|
|
|
|
|
|
|
52
|
268
|
|
|
|
|
598
|
foreach my $r (@keys) { |
|
53
|
268
|
|
|
|
|
535
|
my ($field, $ifs_match) = @$r; |
|
54
|
268
|
50
|
|
|
|
890
|
if (! $checked{$field}++) { |
|
55
|
268
|
|
|
|
|
697
|
$self->{'was_checked'}->{$field} = 1; |
|
56
|
268
|
|
|
|
|
467
|
$self->{'was_valid'}->{$field} = 1; |
|
57
|
268
|
|
|
|
|
529
|
$self->{'had_error'}->{$field} = 0; |
|
58
|
|
|
|
|
|
|
} |
|
59
|
268
|
|
|
|
|
671
|
local $ref->{'was_validated'} = 1; |
|
60
|
268
|
|
|
|
|
772
|
my $err = $self->validate_buddy($form, $field, $ref, $ifs_match); |
|
61
|
268
|
100
|
|
|
|
724
|
if (!$ref->{'was_validated'}) { |
|
62
|
17
|
|
|
|
|
34
|
$self->{'was_valid'}->{$field} = 0; |
|
63
|
|
|
|
|
|
|
} |
|
64
|
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
# test the error - if errors occur allow for OR - if OR fails use errors from first fail |
|
66
|
268
|
100
|
|
|
|
530
|
if ($err) { |
|
67
|
114
|
|
|
|
|
232
|
$self->{'was_valid'}->{$field} = 0; |
|
68
|
114
|
|
|
|
|
199
|
$self->{'had_error'}->{$field} = 0; |
|
69
|
114
|
50
|
66
|
|
|
351
|
if ($i < $#$fields && ! ref($fields->[$i + 1]) && $fields->[$i + 1] eq 'OR') { |
|
|
|
|
33
|
|
|
|
|
|
70
|
0
|
|
|
|
|
0
|
$hold_error = $err; |
|
71
|
|
|
|
|
|
|
} else { |
|
72
|
114
|
50
|
|
|
|
281
|
push @errors, $hold_error ? @$hold_error : @$err; |
|
73
|
114
|
|
|
|
|
685
|
$hold_error = undef; |
|
74
|
|
|
|
|
|
|
} |
|
75
|
|
|
|
|
|
|
} else { |
|
76
|
154
|
|
|
|
|
894
|
$hold_error = undef; |
|
77
|
|
|
|
|
|
|
} |
|
78
|
|
|
|
|
|
|
} |
|
79
|
|
|
|
|
|
|
} |
|
80
|
250
|
50
|
|
|
|
513
|
push(@errors, @$hold_error) if $hold_error; # allow for final OR to work |
|
81
|
|
|
|
|
|
|
|
|
82
|
250
|
100
|
66
|
|
|
1250
|
$self->no_extra_fields($form,$fields,$val_hash,\@errors) if ($ARGS->{'no_extra_fields'} || $self->{'no_extra_fields'}); |
|
83
|
|
|
|
|
|
|
|
|
84
|
250
|
100
|
|
|
|
1430
|
return if ! @errors; # success |
|
85
|
|
|
|
|
|
|
|
|
86
|
120
|
|
|
|
|
205
|
my %uniq; |
|
87
|
|
|
|
|
|
|
my %error; |
|
88
|
120
|
|
|
|
|
201
|
foreach my $err (@errors) { |
|
89
|
121
|
|
|
|
|
372
|
my ($field, $type, $fv, $ifs_match) = @$err; |
|
90
|
121
|
50
|
|
|
|
281
|
throw "Missing field name", {err => $err} if ! $field; |
|
91
|
121
|
50
|
|
|
|
252
|
if ($fv->{'delegate_error'}) { |
|
92
|
0
|
|
|
|
|
0
|
$field = $fv->{'delegate_error'}; |
|
93
|
0
|
0
|
|
|
|
0
|
$field =~ s/\$(\d+)/defined($ifs_match->[$1]) ? $ifs_match->[$1] : ''/eg if $ifs_match; |
|
|
0
|
0
|
|
|
|
0
|
|
|
94
|
|
|
|
|
|
|
} |
|
95
|
121
|
|
|
|
|
289
|
my $text = $self->get_error_text($err, $ARGS); |
|
96
|
121
|
50
|
|
|
|
1019
|
$error{$field} .= "$text\n" if !$uniq{$field}->{$text}++; |
|
97
|
|
|
|
|
|
|
} |
|
98
|
120
|
|
|
|
|
447
|
chomp $error{$_} for keys %error; |
|
99
|
120
|
50
|
|
|
|
285
|
throw "Validation failed", {errors => \%error} if $ARGS->{'raise_error'}; |
|
100
|
120
|
|
|
|
|
1130
|
return \%error; |
|
101
|
|
|
|
|
|
|
} |
|
102
|
|
|
|
|
|
|
|
|
103
|
|
|
|
|
|
|
sub no_extra_fields { |
|
104
|
26
|
|
|
26
|
0
|
81
|
my ($self,$form,$fields,$fv,$errors,$field_prefix) = @_; |
|
105
|
26
|
|
100
|
|
|
98
|
$field_prefix ||= ''; |
|
106
|
26
|
|
100
|
|
|
123
|
local $self->{'_recurse'} = ($self->{'_recurse'} || 0) + 1; |
|
107
|
26
|
50
|
|
|
|
67
|
throw "Max dependency level reached 10" if $self->{'_recurse'} > 10; |
|
108
|
|
|
|
|
|
|
|
|
109
|
26
|
|
|
|
|
56
|
my %keys = map { ($_->{'field'} => 1) } @$fields; |
|
|
30
|
|
|
|
|
103
|
|
|
110
|
26
|
|
|
|
|
102
|
foreach my $key (sort keys %$form) { |
|
111
|
26
|
100
|
|
|
|
102
|
if (ref $form->{$key} eq 'HASH') { |
|
|
|
100
|
|
|
|
|
|
|
112
|
5
|
|
|
|
|
11
|
my $field_type = $fv->{$key}->{'type'}; |
|
113
|
5
|
100
|
|
|
|
18
|
if(!defined $field_type) { |
|
|
|
50
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
# Do nothing |
|
115
|
|
|
|
|
|
|
} |
|
116
|
|
|
|
|
|
|
elsif (ref $field_type ne 'HASH') { |
|
117
|
0
|
|
|
|
|
0
|
push @$errors, [$field_prefix.$key, 'no_extra_fields', {}, undef]; |
|
118
|
0
|
|
|
|
|
0
|
next; |
|
119
|
|
|
|
|
|
|
} else { |
|
120
|
4
|
|
|
|
|
12
|
my $f = [map { {field=>$_} } keys %$field_type]; |
|
|
4
|
|
|
|
|
15
|
|
|
121
|
4
|
|
|
|
|
38
|
$self->no_extra_fields($form->{$key},$f,$field_type,$errors,$field_prefix.$key.'.'); |
|
122
|
|
|
|
|
|
|
} |
|
123
|
|
|
|
|
|
|
} elsif (ref $form->{$key} eq 'ARRAY') { |
|
124
|
3
|
|
|
|
|
8
|
my $field_type = $fv->{$key}->{'type'}; |
|
125
|
3
|
50
|
|
|
|
15
|
if (!defined $field_type) { |
|
|
|
100
|
|
|
|
|
|
|
126
|
|
|
|
|
|
|
# Do nothing |
|
127
|
|
|
|
|
|
|
} elsif (ref $field_type eq 'HASH') { |
|
128
|
2
|
|
|
|
|
5
|
my $f = [map { {field=>$_} } keys %$field_type]; |
|
|
2
|
|
|
|
|
9
|
|
|
129
|
2
|
|
|
|
|
6
|
foreach (my $i = 0; $i <= $#{$form->{$key}}; $i ++) { |
|
|
8
|
|
|
|
|
28
|
|
|
130
|
6
|
50
|
|
|
|
55
|
$self->no_extra_fields($form->{$key}->[$i],$f,$field_type,$errors,$field_prefix.$key.':'.$i.'.') if ref $form->{$key}->[$i]; |
|
131
|
|
|
|
|
|
|
} |
|
132
|
|
|
|
|
|
|
} |
|
133
|
|
|
|
|
|
|
} |
|
134
|
26
|
100
|
|
|
|
90
|
next if $keys{$key}; |
|
135
|
7
|
|
|
|
|
42
|
push @$errors, [$field_prefix.$key, 'no_extra_fields', {}, undef]; |
|
136
|
|
|
|
|
|
|
} |
|
137
|
|
|
|
|
|
|
} |
|
138
|
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
sub get_ordered_fields { |
|
140
|
254
|
|
|
254
|
0
|
577
|
my ($self, $val_hash) = @_; |
|
141
|
254
|
50
|
33
|
|
|
1143
|
throw "validation must be a hashref" if !$val_hash || ref $val_hash ne 'HASH'; |
|
142
|
254
|
|
|
|
|
446
|
my %ARGS; |
|
143
|
254
|
100
|
|
|
|
1072
|
my @field_keys = grep { /^group\s+(\w+)/ ? do {$ARGS{$1} = $val_hash->{$_}; 0} : 1} sort keys %$val_hash; |
|
|
301
|
|
|
|
|
1276
|
|
|
|
29
|
|
|
|
|
117
|
|
|
|
29
|
|
|
|
|
80
|
|
|
144
|
|
|
|
|
|
|
|
|
145
|
|
|
|
|
|
|
# Look first for items in 'group fields' or 'group order' |
|
146
|
254
|
|
|
|
|
453
|
my $fields; |
|
147
|
254
|
100
|
66
|
|
|
1198
|
if (my $ref = $ARGS{'fields'} || $ARGS{'order'}) { |
|
148
|
1
|
50
|
|
|
|
4
|
my $type = $ARGS{'fields'} ? 'group fields' : 'group order'; |
|
149
|
1
|
50
|
|
|
|
3
|
throw "Validation '$type' must be an arrayref when passed" if ref($ref) ne 'ARRAY'; |
|
150
|
1
|
|
|
|
|
2
|
foreach my $field (@$ref) { |
|
151
|
1
|
50
|
|
|
|
2
|
throw "Non-defined value in '$type'" if ! defined $field; |
|
152
|
1
|
50
|
|
|
|
3
|
if (ref $field) { |
|
|
|
50
|
|
|
|
|
|
|
153
|
0
|
0
|
|
|
|
0
|
throw "Found nonhashref value in '$type'" if ref($field) ne 'HASH'; |
|
154
|
0
|
0
|
|
|
|
0
|
throw "Element missing \"field\" key/value in '$type'" if ! defined $field->{'field'}; |
|
155
|
0
|
|
|
|
|
0
|
push @$fields, $field; |
|
156
|
|
|
|
|
|
|
} elsif ($field eq 'OR') { |
|
157
|
0
|
|
|
|
|
0
|
push @$fields, 'OR'; |
|
158
|
|
|
|
|
|
|
} else { |
|
159
|
1
|
50
|
|
|
|
2
|
throw "No element found in '$type' for $field" if ! exists $val_hash->{$field}; |
|
160
|
1
|
50
|
|
|
|
3
|
throw "Found nonhashref value in '$type'" if ref($val_hash->{$field}) ne 'HASH'; |
|
161
|
1
|
|
|
|
|
1
|
my $val = $val_hash->{$field}; |
|
162
|
1
|
50
|
|
|
|
3
|
$val = {%$val, field => $field} if ! $val->{'field'}; # copy the values to add the key |
|
163
|
1
|
|
|
|
|
2
|
push @$fields, $val; |
|
164
|
|
|
|
|
|
|
} |
|
165
|
|
|
|
|
|
|
} |
|
166
|
|
|
|
|
|
|
|
|
167
|
|
|
|
|
|
|
# limit the keys that need to be searched to those not in fields or order |
|
168
|
1
|
50
|
|
|
|
1
|
my %found = map { ref($_) ? ($_->{'field'} => 1) : () } @$fields; |
|
|
1
|
|
|
|
|
4
|
|
|
169
|
1
|
|
|
|
|
2
|
@field_keys = grep { ! $found{$_} } @field_keys; |
|
|
2
|
|
|
|
|
4
|
|
|
170
|
|
|
|
|
|
|
} |
|
171
|
|
|
|
|
|
|
|
|
172
|
|
|
|
|
|
|
# add any remaining field_vals from our original hash |
|
173
|
|
|
|
|
|
|
# this is necessary for items that weren't in group fields or group order |
|
174
|
254
|
|
|
|
|
618
|
foreach my $field (@field_keys) { |
|
175
|
271
|
50
|
|
|
|
827
|
throw "Found nonhashref value for field $field" if ref($val_hash->{$field}) ne 'HASH'; |
|
176
|
271
|
50
|
|
|
|
699
|
if (defined $val_hash->{$field}->{'field'}) { |
|
177
|
0
|
|
|
|
|
0
|
push @$fields, $val_hash->{$field}; |
|
178
|
|
|
|
|
|
|
} else { |
|
179
|
271
|
|
|
|
|
483
|
push @$fields, { %{$val_hash->{$field}}, field => $field }; |
|
|
271
|
|
|
|
|
1515
|
|
|
180
|
|
|
|
|
|
|
} |
|
181
|
|
|
|
|
|
|
} |
|
182
|
|
|
|
|
|
|
|
|
183
|
254
|
|
50
|
|
|
1095
|
return ($fields || [], \%ARGS); |
|
184
|
|
|
|
|
|
|
} |
|
185
|
|
|
|
|
|
|
|
|
186
|
|
|
|
|
|
|
# allow for optional validation on groups and on individual items |
|
187
|
|
|
|
|
|
|
sub check_conditional { |
|
188
|
40
|
|
|
40
|
0
|
96
|
my ($self, $form, $ifs, $ifs_match) = @_; |
|
189
|
40
|
50
|
|
|
|
76
|
throw "Need reference passed to check_conditional" if ! $ifs; |
|
190
|
40
|
50
|
66
|
|
|
146
|
$ifs = [$ifs] if ! ref($ifs) || ref($ifs) eq 'HASH'; |
|
191
|
|
|
|
|
|
|
|
|
192
|
40
|
|
|
|
|
94
|
local $self->{'_check_conditional'} = 1; |
|
193
|
|
|
|
|
|
|
|
|
194
|
|
|
|
|
|
|
# run the if options here |
|
195
|
|
|
|
|
|
|
# multiple items can be passed - all are required unless OR is used to separate |
|
196
|
40
|
|
|
|
|
62
|
my $found = 1; |
|
197
|
40
|
|
|
|
|
107
|
foreach (my $i = 0; $i <= $#$ifs; $i ++) { |
|
198
|
40
|
|
|
|
|
76
|
my $ref = $ifs->[$i]; |
|
199
|
40
|
100
|
|
|
|
83
|
if (! ref $ref) { |
|
200
|
38
|
50
|
|
|
|
75
|
if ($ref eq 'OR') { |
|
201
|
0
|
0
|
|
|
|
0
|
$i++ if $found; # if found skip the OR altogether |
|
202
|
0
|
|
|
|
|
0
|
$found = 1; # reset |
|
203
|
0
|
|
|
|
|
0
|
next; |
|
204
|
|
|
|
|
|
|
} else { |
|
205
|
38
|
50
|
|
|
|
174
|
if ($ref =~ /^function\s*\(/) { |
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
206
|
0
|
|
|
|
|
0
|
next; |
|
207
|
|
|
|
|
|
|
} elsif ($ref =~ /^(.*?)\s+(was_valid|had_error|was_checked)$/) { |
|
208
|
11
|
|
|
|
|
56
|
$ref = {field => $1, $2 => 1}; |
|
209
|
|
|
|
|
|
|
} elsif ($ref =~ s/^\s*!\s*//) { |
|
210
|
2
|
|
|
|
|
12
|
$ref = {field => $ref, max_in_set => "0 of $ref"}; |
|
211
|
|
|
|
|
|
|
} else { |
|
212
|
25
|
|
|
|
|
81
|
$ref = {field => $ref, required => 1}; |
|
213
|
|
|
|
|
|
|
} |
|
214
|
|
|
|
|
|
|
} |
|
215
|
|
|
|
|
|
|
} |
|
216
|
40
|
50
|
|
|
|
103
|
last if ! $found; |
|
217
|
|
|
|
|
|
|
|
|
218
|
|
|
|
|
|
|
# get the field - allow for custom variables based upon a match |
|
219
|
40
|
|
33
|
|
|
101
|
my $field = $ref->{'field'} || throw "Missing field key during validate_if (possibly used a reference to a main hash *foo -> &foo)"; |
|
220
|
40
|
50
|
|
|
|
102
|
$field =~ s/\$(\d+)/defined($ifs_match->[$1]) ? $ifs_match->[$1] : ''/eg if $ifs_match; |
|
|
7
|
100
|
|
|
|
66
|
|
|
221
|
|
|
|
|
|
|
|
|
222
|
|
|
|
|
|
|
# max_values is properly checked elsewhere, however we need to stub in a value so defaults are properly set |
|
223
|
40
|
100
|
50
|
|
|
110
|
$ref->{'max_values'} ||= scalar @{$form->{$field}} if ref $form->{$field} eq 'ARRAY'; |
|
|
2
|
|
|
|
|
9
|
|
|
224
|
|
|
|
|
|
|
|
|
225
|
40
|
|
|
|
|
132
|
my $errs = $self->validate_buddy($form, $field, $ref); |
|
226
|
|
|
|
|
|
|
|
|
227
|
40
|
100
|
|
|
|
314
|
$found = 0 if $errs; |
|
228
|
|
|
|
|
|
|
} |
|
229
|
40
|
|
|
|
|
173
|
return $found; |
|
230
|
|
|
|
|
|
|
} |
|
231
|
|
|
|
|
|
|
|
|
232
|
|
|
|
|
|
|
|
|
233
|
|
|
|
|
|
|
# this is where the main checking goes on |
|
234
|
|
|
|
|
|
|
sub validate_buddy { |
|
235
|
335
|
|
|
335
|
0
|
841
|
my ($self, $form, $field, $fv, $ifs_match, $field_prefix) = @_; |
|
236
|
335
|
|
100
|
|
|
1382
|
$field_prefix ||= ''; |
|
237
|
335
|
|
100
|
|
|
1243
|
local $self->{'_recurse'} = ($self->{'_recurse'} || 0) + 1; |
|
238
|
335
|
50
|
|
|
|
826
|
throw "Max dependency level reached 10" if $self->{'_recurse'} > 10; |
|
239
|
335
|
|
|
|
|
482
|
my @errors; |
|
240
|
|
|
|
|
|
|
|
|
241
|
335
|
50
|
|
|
|
794
|
if ($fv->{'exclude_cgi'}) { |
|
242
|
0
|
|
|
|
|
0
|
delete $fv->{'was_validated'}; |
|
243
|
0
|
|
|
|
|
0
|
return 0; |
|
244
|
|
|
|
|
|
|
} |
|
245
|
|
|
|
|
|
|
|
|
246
|
|
|
|
|
|
|
# allow for field names that contain regular expressions |
|
247
|
335
|
50
|
|
|
|
954
|
if ($field =~ m/^(!\s*|)m([^\s\w])(.*)\2([eigsmx]*)$/s) { |
|
248
|
0
|
|
|
|
|
0
|
my ($not,$pat,$opt) = ($1,$3,$4); |
|
249
|
0
|
|
|
|
|
0
|
$opt =~ tr/g//d; |
|
250
|
0
|
0
|
|
|
|
0
|
throw "The e option cannot be used on validation keys on field $field" if $opt =~ /e/; |
|
251
|
0
|
|
|
|
|
0
|
foreach my $_field (sort keys %$form) { |
|
252
|
0
|
0
|
0
|
|
|
0
|
next if ($not && $_field =~ m/(?$opt:$pat)/) || (! $not && $_field !~ m/(?$opt:$pat)/); |
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
253
|
0
|
|
|
|
|
0
|
my $errs = $self->validate_buddy($form, $_field, $fv, [undef, $1, $2, $3, $4, $5]); |
|
254
|
0
|
0
|
|
|
|
0
|
push @errors, @$errs if $errs; |
|
255
|
|
|
|
|
|
|
} |
|
256
|
0
|
0
|
|
|
|
0
|
return @errors ? \@errors : 0; |
|
257
|
|
|
|
|
|
|
} |
|
258
|
|
|
|
|
|
|
|
|
259
|
|
|
|
|
|
|
# allow for canonical field name (allows api to present one field name but return a different one) |
|
260
|
|
|
|
|
|
|
# need to do this relatively early since we are changing the value of $field |
|
261
|
335
|
100
|
|
|
|
817
|
if ($fv->{'canonical'}) { |
|
262
|
1
|
|
|
|
|
5
|
my $orig = $fv->{'orig_field'} = $field; |
|
263
|
1
|
|
|
|
|
2
|
$field = $fv->{'canonical'}; |
|
264
|
1
|
|
|
|
|
5
|
$form->{$field} = delete $form->{$orig}; |
|
265
|
|
|
|
|
|
|
} |
|
266
|
|
|
|
|
|
|
|
|
267
|
335
|
100
|
100
|
|
|
851
|
if ($fv->{'was_valid'} && ! $self->{'was_valid'}->{$field}) { return [[$field_prefix.$field, 'was_valid', $fv, $ifs_match]]; } |
|
|
7
|
|
|
|
|
71
|
|
|
268
|
328
|
100
|
66
|
|
|
791
|
if ($fv->{'had_error'} && ! $self->{'had_error'}->{$field}) { return [[$field_prefix.$field, 'had_error', $fv, $ifs_match]]; } |
|
|
3
|
|
|
|
|
18
|
|
|
269
|
325
|
50
|
33
|
|
|
774
|
if ($fv->{'was_checked'} && ! $self->{'was_checked'}->{$field}) { return [[$field_prefix.$field, 'was_checked', $fv, $ifs_match]]; } |
|
|
0
|
|
|
|
|
0
|
|
|
270
|
|
|
|
|
|
|
|
|
271
|
325
|
100
|
100
|
|
|
852
|
if (!exists($form->{$field}) && $fv->{'alias'}) { |
|
272
|
2
|
50
|
|
|
|
5
|
foreach my $alias (ref($fv->{'alias'}) ? @{$fv->{'alias'}} : $fv->{'alias'}) { |
|
|
0
|
|
|
|
|
0
|
|
|
273
|
2
|
100
|
|
|
|
3
|
next if ! exists $form->{$alias}; |
|
274
|
1
|
|
|
|
|
2
|
$form->{$field} = delete $form->{$alias}; |
|
275
|
1
|
|
|
|
|
2
|
last; |
|
276
|
|
|
|
|
|
|
} |
|
277
|
|
|
|
|
|
|
} |
|
278
|
|
|
|
|
|
|
|
|
279
|
|
|
|
|
|
|
# allow for default value |
|
280
|
325
|
100
|
66
|
|
|
855
|
if (defined($fv->{'default'}) |
|
|
|
|
66
|
|
|
|
|
|
281
|
|
|
|
|
|
|
&& (!defined($form->{$field}) || (ref($form->{$field}) eq 'ARRAY' ? !@{ $form->{$field} } : !length($form->{$field})))) { |
|
282
|
5
|
|
|
|
|
18
|
$form->{$field} = $fv->{'default'}; |
|
283
|
|
|
|
|
|
|
} |
|
284
|
|
|
|
|
|
|
|
|
285
|
325
|
100
|
|
|
|
1025
|
my $values = ref($form->{$field}) eq 'ARRAY' ? $form->{$field} : [$form->{$field}]; |
|
286
|
325
|
|
|
|
|
558
|
my $n_values = @$values; |
|
287
|
|
|
|
|
|
|
|
|
288
|
|
|
|
|
|
|
# allow for a few form modifiers |
|
289
|
325
|
|
|
|
|
524
|
my $modified = 0; |
|
290
|
325
|
|
|
|
|
691
|
foreach my $value (@$values) { |
|
291
|
354
|
100
|
|
|
|
801
|
next if ! defined $value; |
|
292
|
289
|
50
|
|
|
|
657
|
if (! $fv->{'do_not_trim'}) { # whitespace |
|
293
|
289
|
50
|
|
|
|
2066
|
$modified = 1 if $value =~ s/( ^\s+ | \s+$ )//xg; |
|
294
|
|
|
|
|
|
|
} |
|
295
|
289
|
50
|
|
|
|
672
|
if ($fv->{'trim_control_chars'}) { |
|
296
|
0
|
0
|
|
|
|
0
|
$modified = 1 if $value =~ y/\t/ /; |
|
297
|
0
|
0
|
|
|
|
0
|
$modified = 1 if $value =~ y/\x00-\x1F//d; |
|
298
|
|
|
|
|
|
|
} |
|
299
|
289
|
50
|
|
|
|
940
|
if ($fv->{'to_upper_case'}) { # uppercase |
|
|
|
50
|
|
|
|
|
|
|
300
|
0
|
|
|
|
|
0
|
$value = uc $value; |
|
301
|
0
|
|
|
|
|
0
|
$modified = 1; |
|
302
|
|
|
|
|
|
|
} elsif ($fv->{'to_lower_case'}) { # lowercase |
|
303
|
0
|
|
|
|
|
0
|
$value = lc $value; |
|
304
|
0
|
|
|
|
|
0
|
$modified = 1; |
|
305
|
|
|
|
|
|
|
} |
|
306
|
|
|
|
|
|
|
} |
|
307
|
|
|
|
|
|
|
|
|
308
|
325
|
|
|
|
|
498
|
my %types; |
|
309
|
325
|
|
|
|
|
1609
|
foreach (sort keys %$fv) { |
|
310
|
987
|
100
|
|
|
|
3716
|
push @{$types{$1}}, $_ if /^ (compare|custom|equals|match|max_in_set|min_in_set|replace|required_if|sql|type|validate_if) _?\d* $/x; |
|
|
229
|
|
|
|
|
1148
|
|
|
311
|
|
|
|
|
|
|
} |
|
312
|
|
|
|
|
|
|
|
|
313
|
|
|
|
|
|
|
# allow for inline specified modifications (ie s/foo/bar/) |
|
314
|
325
|
100
|
|
|
|
892
|
if ($types{'replace'}) { foreach my $type (@{ $types{'replace'} }) { |
|
|
5
|
|
|
|
|
10
|
|
|
|
5
|
|
|
|
|
10
|
|
|
315
|
|
|
|
|
|
|
my $ref = ref($fv->{$type}) eq 'ARRAY' ? $fv->{$type} |
|
316
|
5
|
50
|
|
|
|
26
|
: [split(/\s*\|\|\s*/,$fv->{$type})]; |
|
317
|
5
|
|
|
|
|
11
|
foreach my $rx (@$ref) { |
|
318
|
5
|
50
|
|
|
|
39
|
if ($rx !~ m/^\s*s([^\s\w])(.+)\1(.*)\1([eigsmx]*)$/s) { |
|
319
|
0
|
|
|
|
|
0
|
throw "Not sure how to parse that replace ($rx)"; |
|
320
|
|
|
|
|
|
|
} |
|
321
|
5
|
|
|
|
|
28
|
my ($pat, $swap, $opt) = ($2, $3, $4); |
|
322
|
5
|
50
|
|
|
|
15
|
throw "The e option cannot be used in swap on field $field" if $opt =~ /e/; |
|
323
|
5
|
|
|
|
|
17
|
my $global = $opt =~ s/g//g; |
|
324
|
5
|
|
|
|
|
10
|
$swap =~ s/\\n/\n/g; |
|
325
|
|
|
|
|
|
|
my $expand = sub { # code similar to Template::Alloy::VMethod::vmethod_replace |
|
326
|
9
|
|
|
9
|
|
23
|
my ($text, $start, $end) = @_; |
|
327
|
9
|
|
|
|
|
15
|
my $copy = $swap; |
|
328
|
9
|
|
|
|
|
22
|
$copy =~ s{ \\(\\|\$) | \$ (\d+) }{ |
|
329
|
3
|
50
|
33
|
|
|
35
|
$1 ? $1 |
|
|
|
50
|
|
|
|
|
|
|
330
|
|
|
|
|
|
|
: ($2 > $#$start || $2 == 0) ? '' |
|
331
|
|
|
|
|
|
|
: substr($text, $start->[$2], $end->[$2] - $start->[$2]); |
|
332
|
|
|
|
|
|
|
}exg; |
|
333
|
9
|
|
|
|
|
17
|
$modified = 1; |
|
334
|
9
|
|
|
|
|
88
|
$copy; |
|
335
|
5
|
|
|
|
|
32
|
}; |
|
336
|
5
|
|
|
|
|
11
|
foreach my $value (@$values) { |
|
337
|
5
|
50
|
|
|
|
12
|
next if ! defined $value; |
|
338
|
5
|
100
|
|
|
|
15
|
if ($global) { $value =~ s{(?$opt:$pat)}{ $expand->($value, [@-], [@+]) }eg } |
|
|
4
|
|
|
|
|
341
|
|
|
|
8
|
|
|
|
|
51
|
|
|
339
|
1
|
|
|
|
|
26
|
else { $value =~ s{(?$opt:$pat)}{ $expand->($value, [@-], [@+]) }e } |
|
|
1
|
|
|
|
|
7
|
|
|
340
|
|
|
|
|
|
|
} |
|
341
|
|
|
|
|
|
|
} |
|
342
|
|
|
|
|
|
|
} } |
|
343
|
325
|
100
|
66
|
|
|
840
|
$form->{$field} = $values->[0] if $modified && $n_values == 1; # put them back into the form if we have modified it |
|
344
|
|
|
|
|
|
|
|
|
345
|
|
|
|
|
|
|
# only continue if a validate_if is not present or passes test |
|
346
|
325
|
|
|
|
|
499
|
my $needs_val = 0; |
|
347
|
325
|
|
|
|
|
473
|
my $n_vif = 0; |
|
348
|
325
|
100
|
|
|
|
670
|
if ($types{'validate_if'}) { foreach my $type (@{ $types{'validate_if'} }) { |
|
|
30
|
|
|
|
|
48
|
|
|
|
30
|
|
|
|
|
58
|
|
|
349
|
30
|
|
|
|
|
45
|
$n_vif++; |
|
350
|
30
|
|
|
|
|
57
|
my $ifs = $fv->{$type}; |
|
351
|
30
|
|
|
|
|
87
|
my $ret = $self->check_conditional($form, $ifs, $ifs_match); |
|
352
|
30
|
100
|
|
|
|
82
|
$needs_val++ if $ret; |
|
353
|
|
|
|
|
|
|
} } |
|
354
|
325
|
100
|
100
|
|
|
1226
|
if (! $needs_val && $n_vif) { |
|
355
|
17
|
|
|
|
|
30
|
delete $fv->{'was_validated'}; |
|
356
|
17
|
|
|
|
|
70
|
return 0; |
|
357
|
|
|
|
|
|
|
} |
|
358
|
|
|
|
|
|
|
|
|
359
|
|
|
|
|
|
|
# check for simple existence |
|
360
|
|
|
|
|
|
|
# optionally check only if another condition is met |
|
361
|
308
|
100
|
|
|
|
797
|
my $is_required = $fv->{'required'} ? 'required' : ''; |
|
362
|
308
|
100
|
|
|
|
627
|
if (! $is_required) { |
|
363
|
249
|
100
|
|
|
|
625
|
if ($types{'required_if'}) { foreach my $type (@{ $types{'required_if'} }) { |
|
|
2
|
|
|
|
|
4
|
|
|
|
2
|
|
|
|
|
3
|
|
|
364
|
2
|
|
|
|
|
3
|
my $ifs = $fv->{$type}; |
|
365
|
2
|
100
|
|
|
|
6
|
next if ! $self->check_conditional($form, $ifs, $ifs_match); |
|
366
|
1
|
|
|
|
|
2
|
$is_required = $type; |
|
367
|
1
|
|
|
|
|
2
|
last; |
|
368
|
|
|
|
|
|
|
} } |
|
369
|
|
|
|
|
|
|
} |
|
370
|
308
|
100
|
66
|
|
|
998
|
if ($is_required |
|
|
|
|
100
|
|
|
|
|
|
371
|
|
|
|
|
|
|
&& ($n_values == 0 || ($n_values == 1 && (! defined($values->[0]) || ! length $values->[0])))) { |
|
372
|
24
|
100
|
|
|
|
90
|
return [] if $self->{'_check_conditional'}; |
|
373
|
13
|
|
|
|
|
87
|
return [[$field_prefix.$field, $is_required, $fv, $ifs_match]]; |
|
374
|
|
|
|
|
|
|
} |
|
375
|
|
|
|
|
|
|
|
|
376
|
284
|
100
|
50
|
|
|
638
|
my $n = exists($fv->{'min_values'}) ? $fv->{'min_values'} || 0 : 0; |
|
377
|
284
|
100
|
|
|
|
596
|
if ($n_values < $n) { |
|
378
|
3
|
50
|
|
|
|
6
|
return [] if $self->{'_check_conditional'}; |
|
379
|
3
|
|
|
|
|
13
|
return [[$field_prefix.$field, 'min_values', $fv, $ifs_match]]; |
|
380
|
|
|
|
|
|
|
} |
|
381
|
|
|
|
|
|
|
|
|
382
|
281
|
100
|
50
|
|
|
1129
|
$fv->{'max_values'} = $fv->{'min_values'} || 1 if ! exists $fv->{'max_values'}; |
|
383
|
281
|
|
50
|
|
|
633
|
$n = $fv->{'max_values'} || 0; |
|
384
|
281
|
100
|
|
|
|
616
|
if ($n_values > $n) { |
|
385
|
4
|
50
|
|
|
|
8
|
return [] if $self->{'_check_conditional'}; |
|
386
|
4
|
|
|
|
|
26
|
return [[$field_prefix.$field, 'max_values', $fv, $ifs_match]]; |
|
387
|
|
|
|
|
|
|
} |
|
388
|
|
|
|
|
|
|
|
|
389
|
277
|
|
|
|
|
956
|
foreach ([min => $types{'min_in_set'}], |
|
390
|
|
|
|
|
|
|
[max => $types{'max_in_set'}]) { |
|
391
|
551
|
|
100
|
|
|
1304
|
my $keys = $_->[1] || next; |
|
392
|
14
|
|
|
|
|
22
|
my $minmax = $_->[0]; |
|
393
|
14
|
|
|
|
|
29
|
foreach my $type (@$keys) { |
|
394
|
14
|
50
|
|
|
|
111
|
$fv->{$type} =~ m/^\s*(\d+)(?i:\s*of)?\s+(.+)\s*$/ |
|
395
|
|
|
|
|
|
|
|| throw "Invalid ${minmax}_in_set check $fv->{$type}"; |
|
396
|
14
|
|
|
|
|
39
|
my $n = $1; |
|
397
|
14
|
|
|
|
|
91
|
foreach my $_field (split /[\s,]+/, $2) { |
|
398
|
38
|
100
|
|
|
|
116
|
my $ref = ref($form->{$_field}) eq 'ARRAY' ? $form->{$_field} : [$form->{$_field}]; |
|
399
|
38
|
|
|
|
|
67
|
foreach my $_value (@$ref) { |
|
400
|
42
|
100
|
100
|
|
|
185
|
$n -- if defined($_value) && length($_value); |
|
401
|
|
|
|
|
|
|
} |
|
402
|
|
|
|
|
|
|
} |
|
403
|
14
|
100
|
100
|
|
|
159
|
if ( ($minmax eq 'min' && $n > 0) |
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
404
|
|
|
|
|
|
|
|| ($minmax eq 'max' && $n < 0)) { |
|
405
|
6
|
100
|
|
|
|
37
|
return [] if $self->{'_check_conditional'}; |
|
406
|
5
|
|
|
|
|
53
|
return [[$field_prefix.$field, $type, $fv, $ifs_match]]; |
|
407
|
|
|
|
|
|
|
} |
|
408
|
|
|
|
|
|
|
} |
|
409
|
|
|
|
|
|
|
} |
|
410
|
|
|
|
|
|
|
|
|
411
|
|
|
|
|
|
|
# at this point @errors should still be empty |
|
412
|
271
|
|
|
|
|
720
|
my $content_checked; # allow later for possible untainting (only happens if content was checked) |
|
413
|
|
|
|
|
|
|
|
|
414
|
271
|
|
|
|
|
508
|
OUTER: foreach my $value (@$values) { |
|
415
|
|
|
|
|
|
|
|
|
416
|
280
|
100
|
|
|
|
663
|
if (exists $fv->{'enum'}) { |
|
417
|
10
|
100
|
|
|
|
40
|
my $ref = ref($fv->{'enum'}) ? $fv->{'enum'} : [split(/\s*\|\|\s*/,$fv->{'enum'})]; |
|
418
|
10
|
|
|
|
|
13
|
my $found = 0; |
|
419
|
10
|
|
|
|
|
12
|
foreach (@$ref) { |
|
420
|
30
|
100
|
100
|
|
|
63
|
$found = 1 if defined($value) && $_ eq $value; |
|
421
|
|
|
|
|
|
|
} |
|
422
|
10
|
100
|
|
|
|
14
|
if (! $found) { |
|
423
|
3
|
50
|
|
|
|
4
|
return [] if $self->{'_check_conditional'}; |
|
424
|
3
|
|
|
|
|
8
|
push @errors, [$field_prefix.$field, 'enum', $fv, $ifs_match]; |
|
425
|
3
|
|
|
|
|
5
|
next OUTER; |
|
426
|
|
|
|
|
|
|
} |
|
427
|
7
|
|
|
|
|
11
|
$content_checked = 1; |
|
428
|
|
|
|
|
|
|
} |
|
429
|
|
|
|
|
|
|
|
|
430
|
|
|
|
|
|
|
# do specific type checks |
|
431
|
277
|
100
|
|
|
|
628
|
if (exists $fv->{'type'}) { |
|
432
|
103
|
100
|
|
|
|
325
|
if (! $self->check_type($value, $fv->{'type'}, $field, $form)){ |
|
433
|
45
|
50
|
|
|
|
128
|
return [] if $self->{'_check_conditional'}; |
|
434
|
45
|
|
|
|
|
174
|
push @errors, [$field_prefix.$field, 'type', $fv, $ifs_match]; |
|
435
|
45
|
|
|
|
|
139
|
next OUTER; |
|
436
|
58
|
50
|
66
|
|
|
211
|
} if (ref($fv->{'type'}) eq 'HASH' && $form->{$field}) { |
|
437
|
|
|
|
|
|
|
# recursively check these |
|
438
|
17
|
|
|
|
|
24
|
foreach my $key (keys %{$fv->{'type'}}) { |
|
|
17
|
|
|
|
|
52
|
|
|
439
|
17
|
100
|
|
|
|
25
|
foreach my $subform (@{ref($form->{$field}) eq 'ARRAY' ? $form->{$field} : [$form->{$field}]}) { |
|
|
17
|
|
|
|
|
62
|
|
|
440
|
27
|
|
|
|
|
159
|
my $errs = $self->validate_buddy($subform, $key, $fv->{'type'}->{$key},[],$field_prefix.$field.'.'); |
|
441
|
27
|
100
|
|
|
|
149
|
push @errors, @$errs if $errs; |
|
442
|
|
|
|
|
|
|
} |
|
443
|
|
|
|
|
|
|
} |
|
444
|
17
|
100
|
|
|
|
101
|
return @errors ? \@errors : 0; |
|
445
|
|
|
|
|
|
|
} |
|
446
|
41
|
|
|
|
|
77
|
$content_checked = 1; |
|
447
|
|
|
|
|
|
|
} |
|
448
|
|
|
|
|
|
|
|
|
449
|
|
|
|
|
|
|
# field equals another field |
|
450
|
215
|
100
|
|
|
|
437
|
if ($types{'equals'}) { foreach my $type (@{ $types{'equals'} }) { |
|
|
9
|
|
|
|
|
17
|
|
|
|
9
|
|
|
|
|
23
|
|
|
451
|
9
|
|
|
|
|
19
|
my $field2 = $fv->{$type}; |
|
452
|
9
|
50
|
|
|
|
24
|
my $not = ($field2 =~ s/^!\s*//) ? 1 : 0; |
|
453
|
9
|
|
|
|
|
17
|
my $success = 0; |
|
454
|
9
|
100
|
|
|
|
31
|
if ($field2 =~ m/^([\"\'])(.*)\1$/) { |
|
455
|
2
|
|
66
|
|
|
18
|
$success = (defined($value) && $value eq $2); |
|
456
|
|
|
|
|
|
|
} else { |
|
457
|
7
|
50
|
|
|
|
25
|
$field2 =~ s/\$(\d+)/defined($ifs_match->[$1]) ? $ifs_match->[$1] : ''/eg if $ifs_match; |
|
|
2
|
100
|
|
|
|
16
|
|
|
458
|
7
|
100
|
66
|
|
|
39
|
if (exists($form->{$field2}) && defined($form->{$field2})) { |
|
|
|
100
|
|
|
|
|
|
|
459
|
5
|
|
100
|
|
|
24
|
$success = (defined($value) && $value eq $form->{$field2}); |
|
460
|
|
|
|
|
|
|
} elsif (! defined($value)) { |
|
461
|
1
|
|
|
|
|
2
|
$success = 1; # occurs if they are both undefined |
|
462
|
|
|
|
|
|
|
} |
|
463
|
|
|
|
|
|
|
} |
|
464
|
9
|
50
|
|
|
|
29
|
if ($not ? $success : ! $success) { |
|
|
|
100
|
|
|
|
|
|
|
465
|
5
|
50
|
|
|
|
14
|
return [] if $self->{'_check_conditional'}; |
|
466
|
5
|
|
|
|
|
21
|
push @errors, [$field_prefix.$field, $type, $fv, $ifs_match]; |
|
467
|
5
|
|
|
|
|
20
|
next OUTER; |
|
468
|
|
|
|
|
|
|
} |
|
469
|
4
|
|
|
|
|
12
|
$content_checked = 1; |
|
470
|
|
|
|
|
|
|
} } |
|
471
|
|
|
|
|
|
|
|
|
472
|
210
|
100
|
|
|
|
444
|
if (exists $fv->{'min_len'}) { |
|
473
|
4
|
|
|
|
|
8
|
my $n = $fv->{'min_len'}; |
|
474
|
4
|
100
|
100
|
|
|
23
|
if (! defined($value) || length($value) < $n) { |
|
475
|
3
|
50
|
|
|
|
8
|
return [] if $self->{'_check_conditional'}; |
|
476
|
3
|
|
|
|
|
14
|
push @errors, [$field_prefix.$field, 'min_len', $fv, $ifs_match]; |
|
477
|
|
|
|
|
|
|
} |
|
478
|
|
|
|
|
|
|
} |
|
479
|
|
|
|
|
|
|
|
|
480
|
210
|
100
|
|
|
|
463
|
if (exists $fv->{'max_len'}) { |
|
481
|
27
|
|
|
|
|
68
|
my $n = $fv->{'max_len'}; |
|
482
|
27
|
100
|
100
|
|
|
136
|
if (defined($value) && length($value) > $n) { |
|
483
|
1
|
50
|
|
|
|
5
|
return [] if $self->{'_check_conditional'}; |
|
484
|
1
|
|
|
|
|
7
|
push @errors, [$field_prefix.$field, 'max_len', $fv, $ifs_match]; |
|
485
|
|
|
|
|
|
|
} |
|
486
|
|
|
|
|
|
|
} |
|
487
|
|
|
|
|
|
|
|
|
488
|
|
|
|
|
|
|
# now do match types |
|
489
|
210
|
100
|
|
|
|
578
|
if ($types{'match'}) { foreach my $type (@{ $types{'match'} }) { |
|
|
15
|
|
|
|
|
24
|
|
|
|
15
|
|
|
|
|
36
|
|
|
490
|
|
|
|
|
|
|
my $ref = ref($fv->{$type}) eq 'ARRAY' ? $fv->{$type} |
|
491
|
|
|
|
|
|
|
: ref($fv->{$type}) eq 'Regexp' ? [$fv->{$type}] |
|
492
|
15
|
100
|
|
|
|
93
|
: [split(/\s*\|\|\s*/,$fv->{$type})]; |
|
|
|
100
|
|
|
|
|
|
|
493
|
15
|
|
|
|
|
36
|
foreach my $rx (@$ref) { |
|
494
|
19
|
100
|
|
|
|
47
|
if (ref($rx) eq 'Regexp') { |
|
495
|
6
|
100
|
66
|
|
|
66
|
if (! defined($value) || $value !~ $rx) { |
|
496
|
2
|
|
|
|
|
58
|
push @errors, [$field_prefix.$field, $type, $fv, $ifs_match]; |
|
497
|
|
|
|
|
|
|
} |
|
498
|
|
|
|
|
|
|
} else { |
|
499
|
13
|
50
|
|
|
|
86
|
if ($rx !~ m/^(!\s*|)m([^\s\w])(.*)\2([eigsmx]*)$/s) { |
|
500
|
0
|
|
|
|
|
0
|
throw "Not sure how to parse that match ($rx)"; |
|
501
|
|
|
|
|
|
|
} |
|
502
|
13
|
|
|
|
|
63
|
my ($not, $pat, $opt) = ($1, $3, $4); |
|
503
|
13
|
|
|
|
|
26
|
$opt =~ tr/g//d; |
|
504
|
13
|
50
|
|
|
|
54
|
throw "The e option cannot be used on validation keys on field $field" if $opt =~ /e/; |
|
505
|
13
|
100
|
100
|
|
|
527
|
if ( ( $not && ( defined($value) && $value =~ m/(?$opt:$pat)/)) |
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
506
|
|
|
|
|
|
|
|| (! $not && (! defined($value) || $value !~ m/(?$opt:$pat)/)) ) { |
|
507
|
6
|
50
|
|
|
|
22
|
return [] if $self->{'_check_conditional'}; |
|
508
|
6
|
|
|
|
|
30
|
push @errors, [$field_prefix.$field, $type, $fv, $ifs_match]; |
|
509
|
|
|
|
|
|
|
} |
|
510
|
|
|
|
|
|
|
} |
|
511
|
|
|
|
|
|
|
} |
|
512
|
15
|
|
|
|
|
43
|
$content_checked = 1; |
|
513
|
|
|
|
|
|
|
} } |
|
514
|
|
|
|
|
|
|
|
|
515
|
|
|
|
|
|
|
# allow for comparison checks |
|
516
|
210
|
100
|
|
|
|
457
|
if ($types{'compare'}) { foreach my $type (@{ $types{'compare'} }) { |
|
|
38
|
|
|
|
|
57
|
|
|
|
38
|
|
|
|
|
91
|
|
|
517
|
38
|
50
|
|
|
|
207
|
my $ref = ref($fv->{$type}) eq 'ARRAY' ? $fv->{$type} : [split(/\s*\|\|\s*/, $fv->{$type})]; |
|
518
|
38
|
|
|
|
|
91
|
foreach my $comp (@$ref) { |
|
519
|
38
|
50
|
|
|
|
87
|
next if ! $comp; |
|
520
|
38
|
|
|
|
|
65
|
my $test = 0; |
|
521
|
38
|
100
|
|
|
|
282
|
if ($comp =~ /^\s*(>|<|[>
|
|
|
|
50
|
|
|
|
|
|
|
522
|
19
|
|
|
|
|
95
|
my ($op, $value2, $field2) = ($1, $2, $3); |
|
523
|
19
|
100
|
|
|
|
45
|
if ($field2) { |
|
524
|
4
|
0
|
|
|
|
13
|
$field2 =~ s/\$(\d+)/defined($ifs_match->[$1]) ? $ifs_match->[$1] : ''/eg if $ifs_match; |
|
|
0
|
50
|
|
|
|
0
|
|
|
525
|
4
|
100
|
|
|
|
13
|
$value2 = exists($form->{$field2}) ? $form->{$field2} * 1 : 0; |
|
526
|
|
|
|
|
|
|
} |
|
527
|
19
|
|
100
|
|
|
52
|
my $val = $value || 0; |
|
528
|
19
|
|
|
|
|
34
|
$val *= 1; |
|
529
|
19
|
100
|
|
|
|
83
|
if ($op eq '>' ) { $test = ($val > $value2) } |
|
|
3
|
100
|
|
|
|
10
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
530
|
3
|
|
|
|
|
10
|
elsif ($op eq '<' ) { $test = ($val < $value2) } |
|
531
|
2
|
|
|
|
|
8
|
elsif ($op eq '>=') { $test = ($val >= $value2) } |
|
532
|
6
|
|
|
|
|
16
|
elsif ($op eq '<=') { $test = ($val <= $value2) } |
|
533
|
2
|
|
|
|
|
8
|
elsif ($op eq '!=') { $test = ($val != $value2) } |
|
534
|
3
|
|
|
|
|
10
|
elsif ($op eq '==') { $test = ($val == $value2) } |
|
535
|
|
|
|
|
|
|
|
|
536
|
|
|
|
|
|
|
} elsif ($comp =~ /^\s*(eq|ne|gt|ge|lt|le)\s+(field:(.+)|.+?)\s*$/) { |
|
537
|
19
|
100
|
|
|
|
52
|
my $val = defined($value) ? $value : ''; |
|
538
|
19
|
|
|
|
|
88
|
my ($op, $value2, $field2) = ($1, $2, $3); |
|
539
|
19
|
100
|
|
|
|
111
|
if ($field2) { |
|
540
|
4
|
0
|
|
|
|
12
|
$field2 =~ s/\$(\d+)/defined($ifs_match->[$1]) ? $ifs_match->[$1] : ''/eg if $ifs_match; |
|
|
0
|
50
|
|
|
|
0
|
|
|
541
|
4
|
100
|
|
|
|
12
|
$value2 = defined($form->{$field2}) ? $form->{$field2} : ''; |
|
542
|
|
|
|
|
|
|
} else { |
|
543
|
15
|
|
|
|
|
60
|
$value2 =~ s/^([\"\'])(.*)\1$/$2/; |
|
544
|
|
|
|
|
|
|
} |
|
545
|
19
|
100
|
|
|
|
84
|
if ($op eq 'gt') { $test = ($val gt $value2) } |
|
|
3
|
100
|
|
|
|
7
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
546
|
3
|
|
|
|
|
9
|
elsif ($op eq 'lt') { $test = ($val lt $value2) } |
|
547
|
2
|
|
|
|
|
7
|
elsif ($op eq 'ge') { $test = ($val ge $value2) } |
|
548
|
6
|
|
|
|
|
17
|
elsif ($op eq 'le') { $test = ($val le $value2) } |
|
549
|
2
|
|
|
|
|
6
|
elsif ($op eq 'ne') { $test = ($val ne $value2) } |
|
550
|
3
|
|
|
|
|
8
|
elsif ($op eq 'eq') { $test = ($val eq $value2) } |
|
551
|
|
|
|
|
|
|
|
|
552
|
|
|
|
|
|
|
} else { |
|
553
|
0
|
|
|
|
|
0
|
throw "Not sure how to compare \"$comp\""; |
|
554
|
|
|
|
|
|
|
} |
|
555
|
38
|
100
|
|
|
|
98
|
if (! $test) { |
|
556
|
20
|
50
|
|
|
|
94
|
return [] if $self->{'_check_conditional'}; |
|
557
|
20
|
|
|
|
|
97
|
push @errors, [$field_prefix.$field, $type, $fv, $ifs_match]; |
|
558
|
|
|
|
|
|
|
} |
|
559
|
|
|
|
|
|
|
} |
|
560
|
38
|
|
|
|
|
100
|
$content_checked = 1; |
|
561
|
|
|
|
|
|
|
} } |
|
562
|
|
|
|
|
|
|
|
|
563
|
|
|
|
|
|
|
# server side sql type |
|
564
|
210
|
50
|
|
|
|
412
|
if ($types{'sql'}) { foreach my $type (@{ $types{'sql'} }) { |
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
565
|
0
|
|
|
|
|
0
|
my $db_type = $fv->{"${type}_db_type"}; |
|
566
|
0
|
0
|
|
|
|
0
|
my $dbh = ($db_type) ? $self->{dbhs}->{$db_type} : $self->{dbh}; |
|
567
|
0
|
0
|
|
|
|
0
|
if (! $dbh) { |
|
|
|
0
|
|
|
|
|
|
|
568
|
0
|
0
|
|
|
|
0
|
throw "Missing dbh for $type type on field $field" . ($db_type ? " and db_type $db_type" : ""); |
|
569
|
|
|
|
|
|
|
} elsif (ref($dbh) eq 'CODE') { |
|
570
|
0
|
|
0
|
|
|
0
|
$dbh = &$dbh($field, $self) || throw "SQL Coderef did not return a dbh"; |
|
571
|
|
|
|
|
|
|
} |
|
572
|
0
|
|
|
|
|
0
|
my $sql = $fv->{$type}; |
|
573
|
0
|
|
|
|
|
0
|
my @args = ($value) x $sql =~ tr/?//; |
|
574
|
0
|
|
|
|
|
0
|
my $return = $dbh->selectrow_array($sql, {}, @args); # is this right - copied from O::FORMS |
|
575
|
0
|
0
|
|
|
|
0
|
$fv->{"${type}_error_if"} = 1 if ! defined $fv->{"${type}_error_if"}; |
|
576
|
0
|
0
|
0
|
|
|
0
|
if ( (! $return && $fv->{"${type}_error_if"}) |
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
577
|
|
|
|
|
|
|
|| ($return && ! $fv->{"${type}_error_if"}) ) { |
|
578
|
0
|
0
|
|
|
|
0
|
return [] if $self->{'_check_conditional'}; |
|
579
|
0
|
|
|
|
|
0
|
push @errors, [$field_prefix.$field, $type, $fv, $ifs_match]; |
|
580
|
|
|
|
|
|
|
} |
|
581
|
0
|
|
|
|
|
0
|
$content_checked = 1; |
|
582
|
|
|
|
|
|
|
} } |
|
583
|
|
|
|
|
|
|
|
|
584
|
|
|
|
|
|
|
# server side custom type |
|
585
|
210
|
100
|
|
|
|
532
|
if ($types{'custom'}) { foreach my $type (@{ $types{'custom'} }) { |
|
|
7
|
|
|
|
|
15
|
|
|
|
7
|
|
|
|
|
18
|
|
|
586
|
7
|
|
|
|
|
13
|
my $check = $fv->{$type}; |
|
587
|
7
|
|
|
|
|
12
|
my $err; |
|
588
|
7
|
100
|
|
|
|
21
|
if (ref($check) eq 'CODE') { |
|
589
|
3
|
|
|
|
|
5
|
my $ok; |
|
590
|
3
|
100
|
|
|
|
7
|
$err = "$@" if ! eval { $ok = $check->($field, $value, $fv, $type, $form); 1 }; |
|
|
3
|
|
|
|
|
15
|
|
|
|
2
|
|
|
|
|
19
|
|
|
591
|
3
|
100
|
|
|
|
24
|
next if $ok; |
|
592
|
2
|
100
|
66
|
|
|
12
|
chomp($err) if !ref($@) && defined($err); |
|
593
|
|
|
|
|
|
|
} else { |
|
594
|
4
|
100
|
|
|
|
13
|
next if $check; |
|
595
|
|
|
|
|
|
|
} |
|
596
|
4
|
50
|
|
|
|
16
|
return [] if $self->{'_check_conditional'}; |
|
597
|
4
|
100
|
|
|
|
21
|
push @errors, [$field_prefix.$field, $type, $fv, $ifs_match, (defined($err) ? $err : ())]; |
|
598
|
4
|
|
|
|
|
13
|
$content_checked = 1; |
|
599
|
|
|
|
|
|
|
} } |
|
600
|
|
|
|
|
|
|
|
|
601
|
|
|
|
|
|
|
} |
|
602
|
|
|
|
|
|
|
|
|
603
|
|
|
|
|
|
|
# allow for the data to be "untainted" |
|
604
|
|
|
|
|
|
|
# this is only allowable if the user ran some other check for the datatype |
|
605
|
254
|
50
|
33
|
|
|
755
|
if ($fv->{'untaint'} && $#errors == -1) { |
|
606
|
0
|
0
|
|
|
|
0
|
if (! $content_checked) { |
|
607
|
0
|
|
|
|
|
0
|
push @errors, [$field_prefix.$field, 'untaint', $fv, $ifs_match]; |
|
608
|
|
|
|
|
|
|
} else { |
|
609
|
|
|
|
|
|
|
# generic untainter - assuming the other required content_checks did good validation |
|
610
|
0
|
0
|
|
|
|
0
|
$_ = /(.*)/ ? $1 : throw "Couldn't match?" foreach @$values; |
|
611
|
0
|
0
|
|
|
|
0
|
if ($n_values == 1) { |
|
612
|
0
|
|
|
|
|
0
|
$form->{$field} = $values->[0]; |
|
613
|
|
|
|
|
|
|
} |
|
614
|
|
|
|
|
|
|
} |
|
615
|
|
|
|
|
|
|
} |
|
616
|
|
|
|
|
|
|
|
|
617
|
254
|
100
|
|
|
|
1474
|
return @errors ? \@errors : 0; |
|
618
|
|
|
|
|
|
|
} |
|
619
|
|
|
|
|
|
|
|
|
620
|
|
|
|
|
|
|
sub check_type { |
|
621
|
103
|
|
|
103
|
0
|
286
|
my ($self, $value, $type) = @_; |
|
622
|
103
|
100
|
|
|
|
347
|
$type = ref($type) eq 'HASH' ? 'hash' : lc $type; |
|
623
|
103
|
50
|
|
|
|
224
|
return 0 if ! defined $value; |
|
624
|
103
|
50
|
|
|
|
649
|
if ($type eq 'email') { |
|
|
|
100
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
625
|
0
|
0
|
|
|
|
0
|
return 0 if ! $value; |
|
626
|
0
|
0
|
|
|
|
0
|
my ($local_p,$dom) = ($value =~ /^(.+)\@(.+?)$/) ? ($1,$2) : return 0; |
|
627
|
0
|
0
|
|
|
|
0
|
return 0 if length($local_p) > 60; |
|
628
|
0
|
0
|
|
|
|
0
|
return 0 if length($dom) > 100; |
|
629
|
0
|
0
|
0
|
|
|
0
|
return 0 if ! $self->check_type($dom,'domain') && ! $self->check_type($dom,'ip'); |
|
630
|
0
|
0
|
|
|
|
0
|
return 0 if ! $self->check_type($local_p,'local_part'); |
|
631
|
|
|
|
|
|
|
} elsif ($type eq 'hash') { |
|
632
|
18
|
100
|
|
|
|
46
|
return 0 if ref $value ne 'HASH'; |
|
633
|
|
|
|
|
|
|
} elsif ($type eq 'local_part') { |
|
634
|
0
|
0
|
|
|
|
0
|
return 0 if ! length($value); |
|
635
|
|
|
|
|
|
|
# ignoring all valid quoted string local parts |
|
636
|
0
|
0
|
|
|
|
0
|
return 0 if $value =~ m/[^\w.~!\#\$%\^&*\-=+?]/; |
|
637
|
|
|
|
|
|
|
} elsif ($type eq 'ip') { |
|
638
|
3
|
50
|
|
|
|
9
|
return 0 if ! $value; |
|
639
|
3
|
50
|
|
|
|
15
|
return (4 == grep {/^\d+$/ && $_ < 256} split /\./, $value, 4); |
|
|
11
|
|
|
|
|
73
|
|
|
640
|
|
|
|
|
|
|
} elsif ($type eq 'domain') { |
|
641
|
9
|
50
|
33
|
|
|
40
|
return 0 if ! $value || length($value) > 255; |
|
642
|
9
|
100
|
100
|
|
|
108
|
return 0 if $value !~ /^(?:[a-z0-9][a-z0-9\-]{0,62} \.)+ [a-z0-9][a-z0-9\-]{0,62}$/ix |
|
643
|
|
|
|
|
|
|
|| $value =~ m/(?:\.\-|\-\.|\.\.)/; |
|
644
|
|
|
|
|
|
|
} elsif ($type eq 'url') { |
|
645
|
0
|
0
|
|
|
|
0
|
return 0 if ! $value; |
|
646
|
0
|
0
|
|
|
|
0
|
$value =~ s|^https?://([^/]+)||i || return 0; |
|
647
|
0
|
|
|
|
|
0
|
my $dom = $1; |
|
648
|
0
|
0
|
0
|
|
|
0
|
return 0 if ! $self->check_type($dom,'domain') && ! $self->check_type($dom,'ip'); |
|
649
|
0
|
0
|
0
|
|
|
0
|
return 0 if $value && ! $self->check_type($value,'uri'); |
|
650
|
|
|
|
|
|
|
} elsif ($type eq 'uri') { |
|
651
|
0
|
0
|
|
|
|
0
|
return 0 if ! $value; |
|
652
|
0
|
0
|
|
|
|
0
|
return 0 if $value =~ m/\s+/; |
|
653
|
|
|
|
|
|
|
} elsif ($type eq 'int') { |
|
654
|
19
|
100
|
|
|
|
134
|
return 0 if $value !~ /^-? (?: 0 | [1-9]\d*) $/x; |
|
655
|
10
|
100
|
|
|
|
48
|
return 0 if ($value < 0) ? $value < -2**31 : $value > 2**31-1; |
|
|
|
100
|
|
|
|
|
|
|
656
|
|
|
|
|
|
|
} elsif ($type eq 'uint') { |
|
657
|
17
|
100
|
|
|
|
118
|
return 0 if $value !~ /^ (?: 0 | [1-9]\d*) $/x; |
|
658
|
6
|
100
|
|
|
|
24
|
return 0 if $value > 2**32-1; |
|
659
|
|
|
|
|
|
|
} elsif ($type eq 'num') { |
|
660
|
19
|
100
|
|
|
|
125
|
return 0 if $value !~ /^-? (?: 0 | [1-9]\d* (?:\.\d+)? | 0?\.\d+) $/x; |
|
661
|
|
|
|
|
|
|
} elsif ($type eq 'unum') { |
|
662
|
18
|
100
|
|
|
|
161
|
return 0 if $value !~ /^ (?: 0 | [1-9]\d* (?:\.\d+)? | 0?\.\d+) $/x; |
|
663
|
|
|
|
|
|
|
} elsif ($type eq 'cc') { |
|
664
|
0
|
0
|
|
|
|
0
|
return 0 if ! $value; |
|
665
|
0
|
0
|
|
|
|
0
|
return 0 if $value =~ /[^\d\-\ ]/; |
|
666
|
0
|
|
|
|
|
0
|
$value =~ s/\D//g; |
|
667
|
0
|
0
|
0
|
|
|
0
|
return 0 if length($value) > 16 || length($value) < 13; |
|
668
|
|
|
|
|
|
|
|
|
669
|
|
|
|
|
|
|
# simple mod10 check |
|
670
|
0
|
|
|
|
|
0
|
my $sum = my $switch = 0; |
|
671
|
0
|
|
|
|
|
0
|
foreach my $digit (reverse split //, $value) { |
|
672
|
0
|
0
|
|
|
|
0
|
$switch = 1 if ++$switch > 2; |
|
673
|
0
|
|
|
|
|
0
|
my $y = $digit * $switch; |
|
674
|
0
|
0
|
|
|
|
0
|
$y -= 9 if $y > 9; |
|
675
|
0
|
|
|
|
|
0
|
$sum += $y; |
|
676
|
|
|
|
|
|
|
} |
|
677
|
0
|
0
|
|
|
|
0
|
return 0 if $sum % 10; |
|
678
|
|
|
|
|
|
|
} |
|
679
|
|
|
|
|
|
|
|
|
680
|
56
|
|
|
|
|
181
|
return 1; |
|
681
|
|
|
|
|
|
|
} |
|
682
|
|
|
|
|
|
|
|
|
683
|
|
|
|
|
|
|
sub get_error_text { |
|
684
|
121
|
|
|
121
|
0
|
252
|
my ($self, $err, $extra) = @_; |
|
685
|
121
|
|
|
|
|
264
|
my ($field, $type, $fv, $ifs_match, $custom_err) = @$err; |
|
686
|
121
|
100
|
66
|
|
|
287
|
return $custom_err if defined($custom_err) && length($custom_err); |
|
687
|
120
|
50
|
|
|
|
900
|
my $dig = ($type =~ s/(_?\d+)$//) ? $1 : ''; |
|
688
|
|
|
|
|
|
|
|
|
689
|
120
|
50
|
|
|
|
306
|
$field = $fv->{'delegate_error'} if $fv->{'delegate_error'}; |
|
690
|
120
|
|
33
|
|
|
404
|
my $name = $fv->{'name'} || $field; |
|
691
|
120
|
0
|
|
|
|
245
|
if ($ifs_match) { s/\$(\d+)/defined($ifs_match->[$1]) ? $ifs_match->[$1] : ''/eg for $field, $name } |
|
|
7
|
100
|
|
|
|
23
|
|
|
|
0
|
|
|
|
|
0
|
|
|
692
|
|
|
|
|
|
|
|
|
693
|
|
|
|
|
|
|
# type can look like "required" or "required2" or "required100023" |
|
694
|
|
|
|
|
|
|
# allow for fallback from required100023_error through required_error |
|
695
|
|
|
|
|
|
|
# look in the passed hash or self first |
|
696
|
120
|
50
|
|
|
|
442
|
foreach my $key ((length($dig) ? "${type}${dig}_error" : ()), "${type}_error", 'error') { |
|
697
|
240
|
|
50
|
|
|
960
|
my $msg = $fv->{$key} || $extra->{$key} || next; |
|
698
|
0
|
0
|
|
|
|
0
|
$msg =~ s/\$(\d+)/defined($ifs_match->[$1]) ? $ifs_match->[$1] : ''/eg if $ifs_match; |
|
|
0
|
0
|
|
|
|
0
|
|
|
699
|
0
|
|
|
|
|
0
|
$msg =~ s/\$field/$field/g; |
|
700
|
0
|
|
|
|
|
0
|
$msg =~ s/\$name/$name/g; |
|
701
|
0
|
0
|
|
|
|
0
|
if (my $value = $fv->{"$type$dig"}) { |
|
702
|
0
|
0
|
|
|
|
0
|
$msg =~ s/\$value/$value/g if ! ref $value; |
|
703
|
|
|
|
|
|
|
} |
|
704
|
0
|
|
|
|
|
0
|
return $msg; |
|
705
|
|
|
|
|
|
|
} |
|
706
|
|
|
|
|
|
|
|
|
707
|
120
|
100
|
100
|
|
|
1074
|
if ($type eq 'required' || $type eq 'required_if') { |
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
708
|
13
|
|
|
|
|
42
|
return "$name is required."; |
|
709
|
|
|
|
|
|
|
} elsif ($type eq 'min_values') { |
|
710
|
3
|
|
|
|
|
5
|
my $n = $fv->{"min_values${dig}"}; |
|
711
|
3
|
50
|
|
|
|
5
|
my $values = ($n == 1) ? 'value' : 'values'; |
|
712
|
3
|
|
|
|
|
8
|
return "$name had less than $n $values."; |
|
713
|
|
|
|
|
|
|
} elsif ($type eq 'max_values') { |
|
714
|
4
|
|
|
|
|
10
|
my $n = $fv->{"max_values${dig}"}; |
|
715
|
4
|
100
|
|
|
|
8
|
my $values = ($n == 1) ? 'value' : 'values'; |
|
716
|
4
|
|
|
|
|
17
|
return "$name had more than $n $values."; |
|
717
|
|
|
|
|
|
|
} elsif ($type eq 'enum') { |
|
718
|
3
|
|
|
|
|
6
|
return "$name is not in the given list."; |
|
719
|
|
|
|
|
|
|
} elsif ($type eq 'equals') { |
|
720
|
5
|
|
|
|
|
15
|
my $field2 = $fv->{"equals${dig}"}; |
|
721
|
5
|
|
33
|
|
|
24
|
my $name2 = $fv->{"equals${dig}_name"} || "the field $field2"; |
|
722
|
5
|
50
|
|
|
|
17
|
$name2 =~ s/\$(\d+)/defined($ifs_match->[$1]) ? $ifs_match->[$1] : ''/eg if $ifs_match; |
|
|
1
|
100
|
|
|
|
9
|
|
|
723
|
5
|
|
|
|
|
24
|
return "$name did not equal $name2."; |
|
724
|
|
|
|
|
|
|
} elsif ($type eq 'min_len') { |
|
725
|
3
|
|
|
|
|
10
|
my $n = $fv->{"min_len${dig}"}; |
|
726
|
3
|
50
|
|
|
|
8
|
my $char = ($n == 1) ? 'character' : 'characters'; |
|
727
|
3
|
|
|
|
|
16
|
return "$name was less than $n $char."; |
|
728
|
|
|
|
|
|
|
} elsif ($type eq 'max_len') { |
|
729
|
1
|
|
|
|
|
5
|
my $n = $fv->{"max_len${dig}"}; |
|
730
|
1
|
50
|
|
|
|
4
|
my $char = ($n == 1) ? 'character' : 'characters'; |
|
731
|
1
|
|
|
|
|
7
|
return "$name was more than $n $char."; |
|
732
|
|
|
|
|
|
|
} elsif ($type eq 'max_in_set') { |
|
733
|
2
|
|
|
|
|
6
|
my $set = $fv->{"max_in_set${dig}"}; |
|
734
|
2
|
|
|
|
|
9
|
return "Too many fields were chosen from the set ($set)"; |
|
735
|
|
|
|
|
|
|
} elsif ($type eq 'min_in_set') { |
|
736
|
3
|
|
|
|
|
11
|
my $set = $fv->{"min_in_set${dig}"}; |
|
737
|
3
|
|
|
|
|
12
|
return "Not enough fields were chosen from the set ($set)"; |
|
738
|
|
|
|
|
|
|
} elsif ($type eq 'match') { |
|
739
|
8
|
|
|
|
|
33
|
return "$name contains invalid characters."; |
|
740
|
|
|
|
|
|
|
} elsif ($type eq 'compare') { |
|
741
|
20
|
|
|
|
|
85
|
return "$name did not fit comparison."; |
|
742
|
|
|
|
|
|
|
} elsif ($type eq 'sql') { |
|
743
|
0
|
|
|
|
|
0
|
return "$name did not match sql test."; |
|
744
|
|
|
|
|
|
|
} elsif ($type eq 'custom') { |
|
745
|
3
|
|
|
|
|
13
|
return "$name did not match custom test."; |
|
746
|
|
|
|
|
|
|
} elsif ($type eq 'type') { |
|
747
|
45
|
|
|
|
|
211
|
my $_type = $fv->{"type${dig}"}; |
|
748
|
45
|
100
|
|
|
|
110
|
$_type = 'hash' if ref($_type) eq 'HASH'; |
|
749
|
45
|
|
|
|
|
175
|
return "$name did not match type $_type."; |
|
750
|
|
|
|
|
|
|
} elsif ($type eq 'untaint') { |
|
751
|
0
|
|
|
|
|
0
|
return "$name cannot be untainted without one of the following checks: enum, equals, match, compare, sql, type, custom"; |
|
752
|
|
|
|
|
|
|
} elsif ($type eq 'no_extra_fields') { |
|
753
|
7
|
|
|
|
|
29
|
return "$name should not be passed to validate."; |
|
754
|
|
|
|
|
|
|
} |
|
755
|
0
|
|
|
|
|
|
throw "Missing error on field $field for type $type$dig"; |
|
756
|
|
|
|
|
|
|
} |
|
757
|
|
|
|
|
|
|
|
|
758
|
|
|
|
|
|
|
1; |