Skip to content

Commit 4950eed

Browse files
author
Eric Wong
committed
git svn: info: correctly handle absolute path args
Calling "git svn info $(pwd)" would hit: "Reading from filehandle failed at ..." errors due to improper prefixing and canonicalization. Strip the toplevel path from absolute filesystem paths to ensure downstream canonicalization routines are only exposed to paths tracked in git (or SVN). v2: Thanks to Andrej Manduch for originally noticing the issue and fixing my original version of this to handle more corner cases such as "/path/to/top/../top" and "/path/to/top/../top/file" as shown in the new test cases. v3: Fix pathname portability problems pointed out by Johannes Sixt with a hint from brian m. carlson. Cc: Johannes Sixt <j6t@kdbg.org> Cc: "brian m. carlson" <sandals@crustytoothpaste.net> Signed-off-by: Andrej Manduch <amanduch@gmail.com> Signed-off-by: Eric Wong <normalperson@yhbt.net>
1 parent 785a1c8 commit 4950eed

File tree

2 files changed

+63
-6
lines changed

2 files changed

+63
-6
lines changed

git-svn.perl

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1477,10 +1477,37 @@ sub cmd_commit_diff {
14771477
}
14781478
}
14791479

1480-
14811480
sub cmd_info {
1482-
my $path = canonicalize_path(defined($_[0]) ? $_[0] : ".");
1483-
my $fullpath = canonicalize_path($cmd_dir_prefix . $path);
1481+
my $path_arg = defined($_[0]) ? $_[0] : '.';
1482+
my $path = $path_arg;
1483+
if (File::Spec->file_name_is_absolute($path)) {
1484+
$path = canonicalize_path($path);
1485+
1486+
my $toplevel = eval {
1487+
my @cmd = qw/rev-parse --show-toplevel/;
1488+
command_oneline(\@cmd, STDERR => 0);
1489+
};
1490+
1491+
# remove $toplevel from the absolute path:
1492+
my ($vol, $dirs, $file) = File::Spec->splitpath($path);
1493+
my (undef, $tdirs, $tfile) = File::Spec->splitpath($toplevel);
1494+
my @dirs = File::Spec->splitdir($dirs);
1495+
my @tdirs = File::Spec->splitdir($tdirs);
1496+
pop @dirs if $dirs[-1] eq '';
1497+
pop @tdirs if $tdirs[-1] eq '';
1498+
push @dirs, $file;
1499+
push @tdirs, $tfile;
1500+
while (@tdirs && @dirs && $tdirs[0] eq $dirs[0]) {
1501+
shift @dirs;
1502+
shift @tdirs;
1503+
}
1504+
$dirs = File::Spec->catdir(@dirs);
1505+
$path = File::Spec->catpath($vol, $dirs);
1506+
1507+
$path = canonicalize_path($path);
1508+
} else {
1509+
$path = canonicalize_path($cmd_dir_prefix . $path);
1510+
}
14841511
if (exists $_[1]) {
14851512
die "Too many arguments specified\n";
14861513
}
@@ -1501,14 +1528,14 @@ sub cmd_info {
15011528
# canonicalize_path() will return "" to make libsvn 1.5.x happy,
15021529
$path = "." if $path eq "";
15031530

1504-
my $full_url = canonicalize_url( add_path_to_url( $url, $fullpath ) );
1531+
my $full_url = canonicalize_url( add_path_to_url( $url, $path ) );
15051532

15061533
if ($_url) {
15071534
print "$full_url\n";
15081535
return;
15091536
}
15101537

1511-
my $result = "Path: $path\n";
1538+
my $result = "Path: $path_arg\n";
15121539
$result .= "Name: " . basename($path) . "\n" if $file_type ne "dir";
15131540
$result .= "URL: $full_url\n";
15141541

@@ -1539,7 +1566,7 @@ sub cmd_info {
15391566
}
15401567

15411568
my ($lc_author, $lc_rev, $lc_date_utc);
1542-
my @args = Git::SVN::Log::git_svn_log_cmd($rev, $rev, "--", $fullpath);
1569+
my @args = Git::SVN::Log::git_svn_log_cmd($rev, $rev, "--", $path);
15431570
my $log = command_output_pipe(@args);
15441571
my $esc_color = qr/(?:\033\[(?:(?:\d+;)*\d*)?m)*/;
15451572
while (<$log>) {

t/t9119-git-svn-info.sh

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,36 @@ test_expect_success 'info .' "
7474
test_cmp_info expected.info-dot actual.info-dot
7575
"
7676

77+
test_expect_success 'info $(pwd)' '
78+
(cd svnwc; svn info "$(pwd)") >expected.info-pwd &&
79+
(cd gitwc; git svn info "$(pwd)") >actual.info-pwd &&
80+
grep -v ^Path: <expected.info-pwd >expected.info-np &&
81+
grep -v ^Path: <actual.info-pwd >actual.info-np &&
82+
test_cmp_info expected.info-np actual.info-np &&
83+
test "$(sed -ne \"/^Path:/ s!/svnwc!!\" <expected.info-pwd)" = \
84+
"$(sed -ne \"/^Path:/ s!/gitwc!!\" <actual.info-pwd)"
85+
'
86+
87+
test_expect_success 'info $(pwd)/../___wc' '
88+
(cd svnwc; svn info "$(pwd)/../svnwc") >expected.info-pwd &&
89+
(cd gitwc; git svn info "$(pwd)/../gitwc") >actual.info-pwd &&
90+
grep -v ^Path: <expected.info-pwd >expected.info-np &&
91+
grep -v ^Path: <actual.info-pwd >actual.info-np &&
92+
test_cmp_info expected.info-np actual.info-np &&
93+
test "$(sed -ne \"/^Path:/ s!/svnwc!!\" <expected.info-pwd)" = \
94+
"$(sed -ne \"/^Path:/ s!/gitwc!!\" <actual.info-pwd)"
95+
'
96+
97+
test_expect_success 'info $(pwd)/../___wc//file' '
98+
(cd svnwc; svn info "$(pwd)/../svnwc//file") >expected.info-pwd &&
99+
(cd gitwc; git svn info "$(pwd)/../gitwc//file") >actual.info-pwd &&
100+
grep -v ^Path: <expected.info-pwd >expected.info-np &&
101+
grep -v ^Path: <actual.info-pwd >actual.info-np &&
102+
test_cmp_info expected.info-np actual.info-np &&
103+
test "$(sed -ne \"/^Path:/ s!/svnwc!!\" <expected.info-pwd)" = \
104+
"$(sed -ne \"/^Path:/ s!/gitwc!!\" <actual.info-pwd)"
105+
'
106+
77107
test_expect_success 'info --url .' '
78108
test "$(cd gitwc; git svn info --url .)" = "$quoted_svnrepo"
79109
'

0 commit comments

Comments
 (0)