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

2588Re: [soaplite] Possible bug in SOAP::Lite

Expand Messages
  • Duncan Cameron
    May 5, 2003
      On 2003-05-04 Vishal Verma wrote:
      >Hi there,
      >
      >What follows is the description of what I think is a
      >bug in SOAP::Lite. It's not a major bug, but may cause
      >you a lot of grief, as it did to me.
      >
      >The function find_target() in Lite.pm, checks if the
      >symbol table for a particular package exists or not,
      >before it loads the module using a "require"
      >statement. Now, the checking the existence of a symbol
      >table is not a confirmatory test of whether a module
      >has already been loaded or not. Consider the following
      >package, for example:
      >
      >package A;
      >
      ># this sub never gets called
      >sub never_call_me
      >{
      > B::foo();
      >}
      >
      >
      >Let's suppose that the SOAP server has both packages A
      >and B specified in dispatch_to list. Now if a request
      >arrives for a function in package A, Perl will parse
      >package A and when it parses sub "never_call_me", it
      >will create the symbol table for B and an empty entry
      >for B::foo. So at this point, the symbol table for B
      >exists, but B hasn't been loaded. Now a request for
      >"foo" in B arrives. It will error out saying "unable
      >to find function foo in package B". The reason being
      >that B was never loaded using a "require B" statement.
      >
      >The right way to check if a package has been loaded or
      >not is to check if an entry for the module in %INC
      >hash. But before you do that, you'll have to translate
      >the colons in the module name to slashes. Here's the
      >patch for the latest version 0.55. You should execute
      >this patch in the SOAP-Lite-0.55 directory as
      >patch -p0 < patchfile
      >
      >The contents of patchfile:
      >
      >--- lib/SOAP/Lite.pm Mon Apr 15 21:42:48 2002
      >+++ lib/SOAP/Lite.pm Fri May 2 17:20:40 2003
      >@@ -2116,7 +2116,9 @@
      > }
      >
      > no strict 'refs';
      >- unless (defined %{"${class}::"}) {
      >+ my $class_inc_entry = $class;
      >+ $class_inc_entry =~ s#::#/#og;
      >+ unless (defined $INC{$class_inc_entry}) {
      > # allow all for static and only specified path
      >for dynamic bindings
      > local @INC = (($static ? @INC : ()), grep {!ref
      >&& m![/\\.]!} $self->dispatch_to);
      > eval 'local $^W; ' . "require $class";
      >
      >
      >If you think I'm missing something, let me know. As
      >such, I don't know about Perl that much.
      >
      A couple of points.
      A package might have been loaded due to it being within the same file as
      another package. For example;

      file A.pm

      package A;

      package A::SubPackageA;

      1;

      Odd perhaps, but still valid. In this case you definitely don't want to
      do a 'require A::SubPackageA;'. So checking %INC isn't quite the right
      thing to do.

      In your case,

      sub never_call_me
      {
      B::foo();
      }

      shouldn't you have a 'use B;' statement anyway.

      Regards,
      Duncan
    • Show all 4 messages in this topic