Skip to content

Commit af2b8fa

Browse files
committed
Merge branch 'rs/pax-extended-header-length-fix'
"git archive" recorded incorrect length in extended pax header in some corner cases, which has been corrected. * rs/pax-extended-header-length-fix: archive-tar: turn length miscalculation warning into BUG archive-tar: use size_t in strbuf_append_ext_header() archive-tar: fix pax extended header length calculation archive-tar: report wrong pax extended header length
2 parents fa9e793 + 71d41ff commit af2b8fa

File tree

2 files changed

+29
-4
lines changed

2 files changed

+29
-4
lines changed

archive-tar.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -142,19 +142,25 @@ static int stream_blocked(const struct object_id *oid)
142142
* string and appends it to a struct strbuf.
143143
*/
144144
static void strbuf_append_ext_header(struct strbuf *sb, const char *keyword,
145-
const char *value, unsigned int valuelen)
145+
const char *value, size_t valuelen)
146146
{
147-
int len, tmp;
147+
size_t orig_len = sb->len;
148+
size_t len, tmp;
148149

149150
/* "%u %s=%s\n" */
150151
len = 1 + 1 + strlen(keyword) + 1 + valuelen + 1;
151-
for (tmp = len; tmp > 9; tmp /= 10)
152+
for (tmp = 1; len / 10 >= tmp; tmp *= 10)
152153
len++;
153154

154155
strbuf_grow(sb, len);
155-
strbuf_addf(sb, "%u %s=", len, keyword);
156+
strbuf_addf(sb, "%"PRIuMAX" %s=", (uintmax_t)len, keyword);
156157
strbuf_add(sb, value, valuelen);
157158
strbuf_addch(sb, '\n');
159+
160+
if (len != sb->len - orig_len)
161+
BUG("pax extended header length miscalculated as %"PRIuMAX
162+
", should be %"PRIuMAX,
163+
(uintmax_t)len, (uintmax_t)(sb->len - orig_len));
158164
}
159165

160166
/*

t/t5004-archive-corner-cases.sh

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,4 +204,23 @@ test_expect_success EXPENSIVE,LONG_IS_64BIT,UNZIP,UNZIP_ZIP64_SUPPORT,ZIPINFO \
204204
grep $size big.lst
205205
'
206206

207+
build_tree() {
208+
perl -e '
209+
my $hash = $ARGV[0];
210+
foreach my $order (2..6) {
211+
$first = 10 ** $order;
212+
foreach my $i (-13..-9) {
213+
my $name = "a" x ($first + $i);
214+
print "100644 blob $hash\t$name\n"
215+
}
216+
}
217+
' "$1"
218+
}
219+
220+
test_expect_success 'tar archive with long paths' '
221+
blob=$(echo foo | git hash-object -w --stdin) &&
222+
tree=$(build_tree $blob | git mktree) &&
223+
git archive -o long_paths.tar $tree
224+
'
225+
207226
test_done

0 commit comments

Comments
 (0)