Commit 9b0a78fb authored by mkanat%bugzilla.org's avatar mkanat%bugzilla.org

Bug 471942: Make the WebService validate and properly convert input parameters

Patch By Max Kanat-Alexander <mkanat@bugzilla.org> r=dkl, a=mkanat
parent 6c6de869
......@@ -97,6 +97,7 @@ sub initialize {
my $self = shift;
my %retval = $self->SUPER::initialize(@_);
$retval{'serializer'} = Bugzilla::WebService::XMLRPC::Serializer->new;
$retval{'deserializer'} = Bugzilla::WebService::XMLRPC::Deserializer->new;
return %retval;
}
......@@ -114,6 +115,74 @@ sub make_response {
1;
# This exists to validate input parameters (which XMLRPC::Lite doesn't do)
# and also, in some cases, to more-usefully decode them.
package Bugzilla::WebService::XMLRPC::Deserializer;
use strict;
# We can't use "use base" because XMLRPC::Serializer doesn't return
# a true value.
eval { require XMLRPC::Lite; };
our @ISA = qw(XMLRPC::Deserializer);
use Bugzilla::Error;
# Some method arguments need to be converted in some way, when they are input.
sub decode_value {
my $self = shift;
my ($type) = @{ $_[0] };
my $value = $self->SUPER::decode_value(@_);
# We only validate/convert certain types here.
return $value if $type !~ /^(?:int|i4|boolean|double|dateTime\.iso8601)$/;
# Though the XML-RPC standard doesn't allow an empty <int>,
# <double>,or <dateTime.iso8601>, we do, and we just say
# "that's undef".
if (grep($type eq $_, qw(int double dateTime))) {
return undef if $value eq '';
}
my $validator = $self->_validation_subs->{$type};
if (!$validator->($value)) {
ThrowUserError('xmlrpc_invalid_value',
{ type => $type, value => $value });
}
# We convert dateTimes to a DB-friendly date format.
if ($type eq 'dateTime.iso8601') {
# We leave off the $ from the end of this regex to allow for possible
# extensions to the XML-RPC date standard.
$value =~ /^(\d{4})(\d{2})(\d{2})T(\d{2}):(\d{2}):(\d{2})/;
$value = "$1-$2-$3 $4:$5:$6";
}
return $value;
}
sub _validation_subs {
my $self = shift;
return $self->{_validation_subs} if $self->{_validation_subs};
# The only place that XMLRPC::Lite stores any sort of validation
# regex is in XMLRPC::Serializer. We want to re-use those regexes here.
my $lookup = Bugzilla::WebService::XMLRPC::Serializer->new->typelookup;
# $lookup is a hash whose values are arrayrefs, and whose keys are the
# names of types. The second item of each arrayref is a subroutine
# that will do our validation for us.
my %validators = map { $_ => $lookup->{$_}->[1] } (keys %$lookup);
# Add a boolean validator
$validators{'boolean'} = sub {$_[0] =~ /^[01]$/};
# Some types have multiple names, or have a different name in
# XMLRPC::Serializer than their standard XML-RPC name.
$validators{'dateTime.iso8601'} = $validators{'dateTime'};
$validators{'i4'} = $validators{'int'};
$self->{_validation_subs} = \%validators;
return \%validators;
}
1;
# This package exists to fix a UTF-8 bug in SOAP::Lite.
# See http://rt.cpan.org/Public/Bug/Display.html?id=32952.
package Bugzilla::WebService::XMLRPC::Serializer;
......@@ -356,3 +425,20 @@ would return something like:
=back
=head1 EXTENSIONS TO THE XML-RPC STANDARD
=head2 Undefined Values
Normally, XML-RPC does not allow empty values for C<int>, C<double>, or
C<dateTime.iso8601> fields. Bugzilla does--it treats empty values as
C<undef> (called C<NULL> or C<None> in some programming languages).
Bugzilla also accepts a type called C<< <nil> >>, which is always considered
to be C<undef>, no matter what it contains.
=begin private
nil is implemented by XMLRPC::Lite, in XMLRPC::Deserializer::decode_value.
=end private
......@@ -48,11 +48,12 @@ use base qw(Exporter);
# comment that it was retired. Also, if an error changes its name, you'll
# have to fix it here.
use constant WS_ERROR_CODE => {
# Generic Bugzilla::Object errors are 50-99.
# Generic errors (Bugzilla::Object and others) are 50-99.
object_not_specified => 50,
param_required => 50,
params_required => 50,
object_does_not_exist => 51,
xmlrpc_invalid_value => 52,
# Bug errors usually occupy the 100-200 range.
improper_bug_id_field_value => 100,
bug_id_does_not_exist => 101,
......
......@@ -1618,6 +1618,11 @@
[% title = "Wrong Token" %]
That token cannot be used to create a user account.
[% ELSIF error == "xmlrpc_invalid_value" %]
"[% value FILTER html %]" is not a valid value for a
&lt;[% type FILTER html %]&gt; field. (See the XML-RPC specification
for details.)
[% ELSIF error == "zero_length_file" %]
[% title = "File Is Empty" %]
The file you are trying to attach is empty, does not exist, or you don't
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment