Skip to content

Commit 2bd108f

Browse files
committed
Merge branch 'pa/import-tars-long-names'
The import-tars script (in contrib/) has been taught to handle tarballs with overly long paths that use PAX extended headers. * pa/import-tars-long-names: import-tars: read overlong names from pax extended header
2 parents 2289880 + 12ecea4 commit 2bd108f

File tree

1 file changed

+29
-2
lines changed

1 file changed

+29
-2
lines changed

contrib/fast-import/import-tars.perl

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,13 +63,22 @@
6363
my $have_top_dir = 1;
6464
my ($top_dir, %files);
6565

66+
my $next_path = '';
67+
6668
while (read(I, $_, 512) == 512) {
6769
my ($name, $mode, $uid, $gid, $size, $mtime,
6870
$chksum, $typeflag, $linkname, $magic,
6971
$version, $uname, $gname, $devmajor, $devminor,
7072
$prefix) = unpack 'Z100 Z8 Z8 Z8 Z12 Z12
7173
Z8 Z1 Z100 Z6
7274
Z2 Z32 Z32 Z8 Z8 Z*', $_;
75+
76+
unless ($next_path eq '') {
77+
# Recover name from previous extended header
78+
$name = $next_path;
79+
$next_path = '';
80+
}
81+
7382
last unless length($name);
7483
if ($name eq '././@LongLink') {
7584
# GNU tar extension
@@ -90,13 +99,31 @@
9099
Z8 Z1 Z100 Z6
91100
Z2 Z32 Z32 Z8 Z8 Z*', $_;
92101
}
93-
next if $name =~ m{/\z};
94102
$mode = oct $mode;
95103
$size = oct $size;
96104
$mtime = oct $mtime;
97105
next if $typeflag == 5; # directory
98106

99-
if ($typeflag != 1) { # handle hard links later
107+
if ($typeflag eq 'x') { # extended header
108+
# If extended header, check for path
109+
my $pax_header = '';
110+
while ($size > 0 && read(I, $_, 512) == 512) {
111+
$pax_header = $pax_header . substr($_, 0, $size);
112+
$size -= 512;
113+
}
114+
115+
my @lines = split /\n/, $pax_header;
116+
foreach my $line (@lines) {
117+
my ($len, $entry) = split / /, $line;
118+
my ($key, $value) = split /=/, $entry;
119+
if ($key eq 'path') {
120+
$next_path = $value;
121+
}
122+
}
123+
next;
124+
} elsif ($name =~ m{/\z}) { # directory
125+
next;
126+
} elsif ($typeflag != 1) { # handle hard links later
100127
print FI "blob\n", "mark :$next_mark\n";
101128
if ($typeflag == 2) { # symbolic link
102129
print FI "data ", length($linkname), "\n",

0 commit comments

Comments
 (0)