Skip Menu |

This queue is for tickets about the CGI-Application-Plugin-ValidateQuery CPAN distribution.

Report information
The Basics
Id: 50565
Status: resolved
Worked: 40 min
Priority: 0/
Queue: CGI-Application-Plugin-ValidateQuery

People
Owner: nate [...] summersault.com
Requestors: matt [...] summersault.com
Cc:
AdminCc:

Bug Information
Severity: Important
Broken in: 1.0.2
Fixed in: v1.0.3



Subject: Fix for proper handling of multivalued query params
Currently, validate_query() does not handle multivalued fields properly. In particular, with a querystring like "?val=1&val=2" the following $app->validate_query({ val => { optional=>0 } }); will change the query to produce something like { val => 'ARRAY(0x8a8e97c)' } rather than the expected { val => ['1', '2'] # or null-separated "12" } Attached is a patch to correct this behavior, along with related tests. The patch also improves the return value of validate_query() so that it more accurately matches the documentation. Thanks! --Matt
Subject: multivalued-fields.patch
diff -rupN CGI-Application-Plugin-ValidateQuery-1.0.2-orig/lib/CGI/Application/Plugin/ValidateQuery.pm CGI-Application-Plugin-ValidateQuery-1.0.2-patched/lib/CGI/Application/Plugin/ValidateQuery.pm --- CGI-Application-Plugin-ValidateQuery-1.0.2-orig/lib/CGI/Application/Plugin/ValidateQuery.pm 2009-07-17 11:29:15.000000000 -0400 +++ CGI-Application-Plugin-ValidateQuery-1.0.2-patched/lib/CGI/Application/Plugin/ValidateQuery.pm 2009-10-16 10:27:14.000000000 -0400 @@ -119,8 +119,9 @@ sub validate_query { croak $log_msg; } - # account for default values. - map { $self->query->param($_ => $validated{$_}) } keys %validated; + # Account for default values, and use the expanded -name / -value + # suntax for CGI to ensure proper handling of multivalued fields. + map { $self->query->param( -name=>$_ , -value=>$validated{$_} ) } keys %validated; return %validated; } diff -rupN CGI-Application-Plugin-ValidateQuery-1.0.2-orig/t/02-validate.t CGI-Application-Plugin-ValidateQuery-1.0.2-patched/t/02-validate.t --- CGI-Application-Plugin-ValidateQuery-1.0.2-orig/t/02-validate.t 2009-07-17 11:29:15.000000000 -0400 +++ CGI-Application-Plugin-ValidateQuery-1.0.2-patched/t/02-validate.t 2009-10-16 10:33:33.000000000 -0400 @@ -36,6 +36,8 @@ $t_obj->validate_query_config( error_mode => 'fail_mode' ); +my %before_q_vars = $t_obj->query->Vars; + my %return_hash; eval { %return_hash = $t_obj->validate_query({ @@ -50,9 +52,21 @@ eval { }); }; is($@, '', "Successful validation"); -my %vars = $t_obj->query->Vars; +my %after_q_vars = $t_obj->query->Vars; + +is_deeply(\%before_q_vars, \%after_q_vars, 'Query not clobbered?'); + +# Don't use query->Vars to compare with %return_hash. +# Below we ensure multivalued field shows up as hashref, +# rather than as a null separated string. +my %query_hash; +for my $p ($t_obj->query->param) { + my @vals = $t_obj->query->param($p); + $query_hash{$p} = scalar @vals > 1 ? \@vals : $vals[0]; +} + +is_deeply(\%query_hash, \%return_hash, 'Proper return?'); -is_deeply(\%vars, \%return_hash, 'Proper return?'); eval { $t_obj->validate_query({ @@ -117,5 +131,3 @@ $t_obj->validate_query({ is($t_obj->query()->param('one'), 410, 'Default set?'); - - diff -rupN CGI-Application-Plugin-ValidateQuery-1.0.2-orig/t/05-extra_fields_optional.t CGI-Application-Plugin-ValidateQuery-1.0.2-patched/t/05-extra_fields_optional.t --- CGI-Application-Plugin-ValidateQuery-1.0.2-orig/t/05-extra_fields_optional.t 2009-07-17 11:29:15.000000000 -0400 +++ CGI-Application-Plugin-ValidateQuery-1.0.2-patched/t/05-extra_fields_optional.t 2009-10-16 10:35:29.000000000 -0400 @@ -13,7 +13,7 @@ use warnings; use CGI; my $t_obj = TestAppWithoutLogger->new( QUERY => CGI->new( - 'one=1&two=2&three=3&four=4' + 'one=1&two=2&three=3&four=4&five=5&five=e' ), ); @@ -22,20 +22,24 @@ is($t_obj->query->param('one'), 1, 'Re is($t_obj->query->param('two'), 2, 'Reality check: Query properly set?'); is($t_obj->query->param('three'), 3, 'Reality check: Query properly set?'); is($t_obj->query->param('four'), 4, 'Reality check: Query properly set?'); +my @value = $t_obj->query->param('five'); +my @test = (5,'e'); +is(@value, @test, 'Reality check: Query properly set?'); + $t_obj->validate_query_config( error_mode => 'fail_mode', ); -my @before_p = sort $t_obj->query->param; +my %before_q_vars = $t_obj->query->Vars; eval { my $output = $t_obj->validate_query({ one => { type=>SCALAR, optional=>0 }, extra_fields_optional => 1, }); }; -my @after_p = sort $t_obj->query->param; +my %after_q_vars = $t_obj->query->Vars; -is_deeply(\@before_p, \@after_p, 'Query not clobbered?'); +is_deeply(\%before_q_vars, \%after_q_vars, 'Query not clobbered?'); unlike($@, qr/not listed in the validation options/, "Properly ignored rest of query?");
I have applied your patch and uploaded v1.0.3 to CPAN. Thanks!