Loading ...
Sorry, an error occurred while loading the content.

Bug in SOAP::Data::type( )

Expand Messages
  • Jay A. Kreibich
    I seem to have found what I consider a bug in the SOAP::Data::type() function. I discovered this while trying to get types from SOAP::data objects. The basic
    Message 1 of 1 , Nov 14, 2006
    • 0 Attachment
      I seem to have found what I consider a bug in the SOAP::Data::type()
      function. I discovered this while trying to get types from
      SOAP::data objects. The basic issue is that if I extract more than
      one SOAP::Data object from the same point in the SOAP::SOM tree, only
      the first SOAP::Data object returns a valid type. All the other
      SOAP::Data objects return a Perl undefined value for the type.

      When you create a SOAP::Data object using SOAP::SOM::dataof(), an
      _attr element is created that points back into the SOAP::SOM tree,
      just as the SOAP::SOM "current" pointer does. Although
      SOAP::SOM::dataof() makes a "local" copy of [SOAP::SOM]->{_current},
      this does not create a deep copy, nor does it do anything else to
      prevent part of the SOAP::Data elements from referencing the same
      data inside the SOAP::SOM object from which the SOAP::Data was derived.

      The problem is that SOAP::Data::type() finds *and deletes* the raw type
      information from the SOAP::Data's "internal" _attr element. Only
      problem is that this still points back to attribute elements in the
      original SOAP::SOM object, so the type attributes are deleted out of
      the master SOAP::SOM tree, not the SOAP::Data object. The SOAP::Data
      object caches this type information as part of the SOAP::Data instance,
      so the first SOAP::Data instance created at a given point on the SOAP::SOM
      tree works as expected. BUT, if you create a new SOAP::Data object at
      the same node in the SOAP::SOM tree, it cannot re-extract the type
      information since it is was deleted by the first SOAP::Data object.

      Looking at the code, I also don't understand *why* the
      SOAP::Data::type() function deletes the attribute information. The
      cache system does no depend on the deletion, so there is no real
      reason to do it (at least, from what I understand of the code).

      The code in question is here:

      ###SOAP/Lite.pm#######################################################
      [...]
      package SOAP::Data;
      [...]

      sub type {
      my $self = UNIVERSAL::isa($_[0] => __PACKAGE__) ? shift->new : __PACKAGE__->new;
      if (@_) {
      $self->{_type} = shift;
      $self->value(@_) if @_;
      return $self;
      }
      if (!defined $self->{_type} && (my @types = grep {/^\{$SOAP::Constants::NS_XSI_ALL}type$/o} keys %{$self->{_attr}})) {
      $self->{_type} = (SOAP::Utils::splitlongname(delete $self->{_attr}->{shift(@types)}))[1];
      }
      return $self->{_type};
      }

      [...]
      ######################################################################

      My solution is to just get rid of the "delete" statement (inside the
      "splitlongnames" call). Everything works as expected, the SOAP::SOM
      object is left alone, and subsequent SOAP::Data objects extract (and
      return!) their type correctly.

      I noticed this in 0.68, but it exists in 0.69 as well. Perl 5.8.5.

      -j
      --
      Jay A. Kreibich | CommTech, Emrg Net Tech Svcs
      jak@... | Campus IT & Edu Svcs
      <http://www.uiuc.edu/~jak> | University of Illinois at U/C
    Your message has been successfully submitted and would be delivered to recipients shortly.