Primary Navigation

Possible bug in SOAP::Lite

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

Message 1 of 4
, May 4, 2003

0 Attachment

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

If you think I'm missing something, let me know. As
such, I don't know about Perl that much.

-vish

__________________________________
Do you Yahoo!?
The New Yahoo! Search - Faster. Easier. Bingo.http://search.yahoo.com

Duncan Cameron

... 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

Message 2 of 4
, May 5, 2003

0 Attachment

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

Vishal Verma

... I have a question. Does it hurt to do a require A::SubPackageA , if A::SubPackageA has already been loaded? What side effects will that have? ...

> 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.

I have a question. Does it hurt to do a "require
A::SubPackageA", if "A::SubPackageA" has already been
loaded? What side effects will that have?

Remember, I told you that nobody calls
"never_call_me". So we don't actually need a "use B;"
statement for this to work. Odd perhaps, but still
valid. I actually saw this happen!

-vish

__________________________________
Do you Yahoo!?
The New Yahoo! Search - Faster. Easier. Bingo.http://search.yahoo.com

Duncan Cameron

... Well in this case the require will fail because there is no such file as A/SubPackageA.pm. But in general you are right, there should be no problem in

Message 4 of 4
, May 7, 2003

0 Attachment

On 2003-05-07 Vishal Verma wrote:

>--- Duncan Cameron <dcameron@...> wrote:
>> 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.
>
>I have a question. Does it hurt to do a "require
>A::SubPackageA", if "A::SubPackageA" has already been
>loaded? What side effects will that have?

Well in this case the 'require' will fail because there is no such file
as A/SubPackageA.pm. But in general you are right, there should be no
problem in requiring a file that has already been loaded (if I read
perlfunc correctly!).
Given this, I am not too sure what SOAP::Lite is really checking for
when it tests the existence of the symbol table for, in your example,
module B.

Regards,
Duncan

Your message has been successfully submitted and would be delivered to recipients shortly.