From: mkanat%bugzilla.org <> Date: Sat, 4 Jul 2009 12:06:57 +0000 (+0000) Subject: Bug 494427: Instead of sending for undef elements in the WebService, just strip... X-Git-Tag: bugzilla-3.4rc1~11 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e5110a07e4bef829c675096932e9a6b6978d23d4;p=thirdparty%2Fbugzilla.git Bug 494427: Instead of sending for undef elements in the WebService, just strip the items from the return value. Patch by Rosie Clarkson r=mkanat, a=mkanat --- diff --git a/Bugzilla/WebService.pm b/Bugzilla/WebService.pm index eddc6c24c0..dce62b9215 100755 --- a/Bugzilla/WebService.pm +++ b/Bugzilla/WebService.pm @@ -14,6 +14,9 @@ # # Contributor(s): Marc Schumann # Max Kanat-Alexander +# Rosie Clarkson +# +# Portions © Crown copyright 2009 - Rosie Clarkson (development@planningportal.gov.uk) for the Planning Portal # This is the base class for $self in WebService method calls. For the # actual RPC server, see Bugzilla::WebService::Server and its subclasses. @@ -273,8 +276,11 @@ Bugzilla also accepts an element called C<< >>, as specified by the XML-RPC extension here: L, which is always considered to be C, no matter what it contains. -Bugzilla uses C<< >> values to return C, C, or -C values which are undefined. +Bugzilla does not use C<< >> values in returned data, because currently +most clients do not support C<< >>. Instead, any fields with C +values will be stripped from the response completely. Therefore +B. =begin private diff --git a/Bugzilla/WebService/Server/XMLRPC.pm b/Bugzilla/WebService/Server/XMLRPC.pm index 2b30bea817..8954969c71 100644 --- a/Bugzilla/WebService/Server/XMLRPC.pm +++ b/Bugzilla/WebService/Server/XMLRPC.pm @@ -141,6 +141,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. @@ -180,6 +181,55 @@ 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)) {