diff options
-rw-r--r-- | Bugzilla/WebService/Server/XMLRPC.pm | 56 |
1 files changed, 54 insertions, 2 deletions
diff --git a/Bugzilla/WebService/Server/XMLRPC.pm b/Bugzilla/WebService/Server/XMLRPC.pm index f2b629088..e85fab95c 100644 --- a/Bugzilla/WebService/Server/XMLRPC.pm +++ b/Bugzilla/WebService/Server/XMLRPC.pm @@ -129,6 +129,7 @@ sub _validation_subs { # 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::XMLRPC::Serializer; +use Scalar::Util qw(blessed); use strict; # We can't use "use base" because XMLRPC::Serializer doesn't return # a true value. @@ -168,6 +169,54 @@ sub encode_object { : @encoded; } +# Removes undefined values so they do not produce invalid XMLRPC. +sub envelope { + my $self = shift; + my ($type, $method, $data) = @_; + # If the type isn't a successful response we don't want to change the values. + if ($type eq 'response'){ + $data = _strip_undefs($data); + } + return $self->SUPER::envelope($type, $method, $data); +} + +# In an XMLRPC response we have to handle hashes of arrays, hashes, scalars, +# Bugzilla objects (reftype = 'HASH') and XMLRPC::Data objects. +# The whole XMLRPC::Data object must be removed if its value key is undefined +# so it cannot be recursed like the other hash type objects. +sub _strip_undefs { + my ($initial) = @_; + if (ref $initial eq "HASH" || (blessed $initial && $initial->isa("HASH"))) { + while (my ($key, $value) = each(%$initial)) { + if ( !defined $value + || (blessed $value && $value->isa('XMLRPC::Data') && !defined $value->value) ) + { + # If the value is undefined remove it from the hash. + delete $initial->{$key}; + } + else { + $initial->{$key} = _strip_undefs($value); + } + } + } + if (ref $initial eq "ARRAY" || (blessed $initial && $initial->isa("ARRAY"))) { + for (my $count = 0; $count < scalar @{$initial}; $count++) { + my $value = $initial->[$count]; + if ( !defined $value + || (blessed $value && $value->isa('XMLRPC::Data') && !defined $value->value) ) + { + # If the value is undefined remove it from the array. + splice(@$initial, $count, 1); + $count--; + } + else { + $initial->[$count] = _strip_undefs($value); + } + } + } + return $initial; +} + sub BEGIN { no strict 'refs'; for my $type (qw(double i4 int dateTime)) { @@ -239,8 +288,11 @@ Bugzilla also accepts an element called C<< <nil> >>, as specified by the XML-RPC extension here: L<http://ontosys.com/xml-rpc/extensions.php>, which is always considered to be C<undef>, no matter what it contains. -Bugzilla uses C<< <nil/> >> values to return C<int>, C<double>, or -C<dateTime.iso8601> values which are undefined. +Bugzilla does not use C<< <nil> >> values in returned data, because currently +most clients do not support C<< <nil> >>. Instead, any fields with C<undef> +values will be stripped from the response completely. Therefore +B<the client must handle the fact that some expected fields may not be +returned>. =begin private |