]> Pileus Git - ~andy/git/commitdiff
git-svn: workaround for a bug in svn serf backend
authorRoman Kagan <rkagan@mail.ru>
Fri, 27 Dec 2013 08:05:15 +0000 (12:05 +0400)
committerEric Wong <normalperson@yhbt.net>
Fri, 27 Dec 2013 20:22:19 +0000 (20:22 +0000)
Subversion serf backend in versions 1.8.5 and below has a bug(*) that the
function creating the descriptor of a file change -- add_file() --
doesn't make a copy of its third argument when storing it on the
returned descriptor.  As a result, by the time this field is used (in
transactions of file copying or renaming) it may well be released, and
the memory reused.

One of its possible manifestations is the svn assertion triggering on an
invalid path, with a message

svn_fspath__skip_ancestor: Assertion
`svn_fspath__is_canonical(child_fspath)' failed.

This patch works around this bug, by storing the value to be passed as
the third argument to add_file() in a local variable with the same scope
as the file change descriptor, making sure their lifetime is the same.

* [ew: fixed in Subversion r1553376 as noted by Jonathan Nieder]

Cc: Benjamin Pabst <benjamin.pabst85@gmail.com>
Signed-off-by: Eric Wong <normalperson@yhbt.net>
Reviewed-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Roman Kagan <rkagan@mail.ru>
perl/Git/SVN/Editor.pm

index b3bcd476daa7d4ab32c30c6fbd2f0a73ec9d0b4f..34e8af966c4a97bd3fafd5d9cfecbfb982f78897 100644 (file)
@@ -304,8 +304,12 @@ sub C {
        my ($self, $m, $deletions) = @_;
        my ($dir, $file) = split_path($m->{file_b});
        my $pbat = $self->ensure_path($dir, $deletions);
+       # workaround for a bug in svn serf backend (v1.8.5 and below):
+       # store third argument to ->add_file() in a local variable, to make it
+       # have the same lifetime as $fbat
+       my $upa = $self->url_path($m->{file_a});
        my $fbat = $self->add_file($self->repo_path($m->{file_b}), $pbat,
-                               $self->url_path($m->{file_a}), $self->{r});
+                               $upa, $self->{r});
        print "\tC\t$m->{file_a} => $m->{file_b}\n" unless $::_q;
        $self->chg_file($fbat, $m);
        $self->close_file($fbat,undef,$self->{pool});
@@ -323,8 +327,10 @@ sub R {
        my ($self, $m, $deletions) = @_;
        my ($dir, $file) = split_path($m->{file_b});
        my $pbat = $self->ensure_path($dir, $deletions);
+       # workaround for a bug in svn serf backend, see comment in C() above
+       my $upa = $self->url_path($m->{file_a});
        my $fbat = $self->add_file($self->repo_path($m->{file_b}), $pbat,
-                               $self->url_path($m->{file_a}), $self->{r});
+                               $upa, $self->{r});
        print "\tR\t$m->{file_a} => $m->{file_b}\n" unless $::_q;
        $self->apply_autoprops($file, $fbat);
        $self->chg_file($fbat, $m);