[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

RE: perl SVN::Client bug

From: Thompson, Thomas J <thomas.j.thompson_at_intel.com>
Date: Tue, 27 Sep 2011 14:22:25 -0700

Or even better,

  $_[$index]->isa('SVN::Client')

This will break if $_[$index] is not a package or object reference, which is exactly what this portion of the code appears to deal with. Best keep it the other way ☺


From: Geoff Rowell [mailto:geoff.rowell_at_gmail.com]
Sent: Tuesday, September 27, 2011 2:14 PM
To: Thompson, Thomas J
Cc: users_at_subversion.apache.org
Subject: Re: perl SVN::Client bug


On Sep 27, 2011, at 4:25 PM, "Thompson, Thomas J" <thomas.j.thompson_at_intel.com<mailto:thomas.j.thompson_at_intel.com>> wrote:
Hi,

I’m an intermediate perl developer with lots to learn, but I think I’ve found an issue with the perl subversion bindings that I’d like to pass by you folks to ensure it’s not just operator error. I would give you the version I’m working with, but I see no VERSION variable in the SVN::Client module. What version information would be useful?

I tried to subclass SVN::Client, but I found that function calls were failing with type errors. I brought this up in this thread on perlmonks:
http://www.perlmonks.org/?node_id=928123

I was seeing errors that look like this:
TypeError in method 'svn_client_ls', argument 2 of type 'char const *'

I found out this section of code handles arguments for calls to the svn functions:
# import methods into our name space and wrap them in a closure
# to support method calling style $ctx->log()
foreach my $function (@_all_fns)
{
    no strict 'refs';
    my $real_function = \&{"SVN::_Client::svn_client_$function"};
    *{"SVN::Client::$function"} = sub
    {
        my ($self, $ctx);
        my @args;

        # Don't shift the first param if it isn't a SVN::Client
        # object. This lets the old style interface still work.
        # And is useful for functions like url_from_path which
        # don't take a ctx param, but might be called in method
        # invocation style or as a normal function.
        for (my $index = $[; $index <= $#_; $index++)
        {
            if (ref($_[$index]) eq 'SVN::Client')
            {
                ($self) = splice(@_,$index,1);
                $ctx = $self->{'ctx'};
                last;
            } elsif (ref($_[$index]) eq '_p_svn_client_ctx_t') {
                $self = undef;
                ($ctx) = splice(@_,$index,1);
                last;
            }
        }

The problem here is this line:
if (ref($_[$index]) eq 'SVN::Client')

This breaks if you attempt to subclass SVN::Client to add functionality. The result is type errors because the invocant is not removed from the function arguments before being passed through to the svn api. This should instead be:

if (UNIVERSAL::isa($_[$index], 'SVN::Client')



What should I do from here to ensure it is addressed? I’d like to help out the perl/svn community.

Or even better,

  $_[$index]->isa('SVN::Client')

-Geoff

Received on 2011-09-27 23:22:58 CEST

This is an archived mail posted to the Subversion Users mailing list.

This site is subject to the Apache Privacy Policy and the Apache Public Forum Archive Policy.