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

Re: Perl Bindings: Assertion svn_uri_is_canonical failed

From: Ben Reser <ben_at_reser.org>
Date: Tue, 27 Jan 2015 13:12:47 -0800

On 1/27/15 9:07 AM, Lathan Bidwell wrote:
> By the way, the SWIG definitions are different enough that they could use their
> own documentation page.

They actually do have a fair amount of documentation. It's just not on a web
page on the website.

Use the perldoc command against the modules e.g.
perldoc SVN::Client
perldoc SVN::Core
and so on...

> However, even fixing that, I am still worried about errors that just crash the
> apache process.

All the SWIG bindings require the user to do their own path canonicalizations.
 You probably want to read this bit of documentation from the C API:
http://subversion.apache.org/docs/api/1.8/svn__dirent__uri_8h.html#details

As mentioned by Stefan Sperling failure to canonicalize paths will result in
undefined behavior, generally aborts(). This is a design decision of the C
APIs. Unfortunately, nobody decided to make the SWIG bindings automatically
canonicalize for you like JavaHL does.

I believe our APIs always provide canonical paths. So any place you're
generating your own paths (and yes URIs are paths) you need to do your own
canonicalization before passing it to the SVN libraries.

I updated the documentation to reflect this last year on trunk, and it'll show
up in the 1.9.0 release.

For instance the following definitions of $path and $target help point you the
right way:
       $path
           This is a path to a file or directory on the local file system.
           Paths need to be canonicalized before being passed into the
           Subversion APIs. Paths on the local file system are called dirents
           and can be canonicalized by calling
           "SVN::Core::dirent_canonicalize".

       $target
           This is a path to a file or directory in a working copy or a URL to
           a file or directory in a subversion repository. Both paths and
           URLs need to be canonicalized before being passed into the
           Subversion APIs. Paths on the local file system are called dirents
           and can be canonicalized by calling
           "SVN::Core::dirent_canonicalize". URLs can be canonicalized by
           calling "SVN::Core::uri_canonicalize".

The example in the SVN::Client has also been updated to show that you should be
doing this:

           use SVN::Client;
           my $client = new SVN::Client();

           # setup to handle authentication the same as the command line client
           my $config_dir = undef; # use default location
           my $config = SVN:Core::config_get_config($config_dir);
           my $config_category = $cfg->{SVN::Core::CONFIG_CATEGORY_CONFIG};
           $client->auth(
             SVN::Core::cmdline_create_auth_baton(0, #non_interactive
                                                  undef, #username
                                                  undef, #password
                                                  $config_dir,
                                                  0, #no_auth_cache
                                                  0, #trust_server_cert
                                                  $config_category,
                                                  undef) #cancel_callback
           );

           # Use first argument as target and canonicalize it before using
           my $target;
           if (SVN::Core::path_is_url($ARGV[0])) {
             $target = SVN::Core::uri_canonicalize($ARGV[0]);
           } else {
             $target = SVN::Core::dirent_canonicalize($ARGV[0]);
           }

           # fetch the head revision of the target
           $client->cat(\*STDOUT, $target, 'HEAD');

> Yes, I'd like to intercept the errors, notify the development email address of
> the error, and give my user a nicer error message.
>
> I'm not that great going through SWIG source, what would it look like?

You'd need to use svn_error_set_malfunction_handler():
http://subversion.apache.org/docs/api/1.8/group__svn__error__malfunction__assertion.html#ga399ab33aa7fcea5cc776a62b56b7ad06

But I don't believe we've got a thunk for that in any SWIG bindings so I don't
think you can actually pass in a Perl function for it to callback when a
malfunction happens. I'll look at wrapping this but it'll take a while to show
up in a released version (either a 1.8.x backport or 1.9.0).

So your more immediate solution is to canonicalize before calling our APIs.
Received on 2015-01-27 22:14:45 CET

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.