Don't lose leading '/' for pathnames exactly 101 bytes long.
Also, update the test harness to exercise this case.
This commit is contained in:
parent
40ca0d5755
commit
8b63161182
@ -278,6 +278,16 @@ __archive_write_format_header_ustar(struct archive_write *a, char h[512],
|
||||
else {
|
||||
/* Store in two pieces, splitting at a '/'. */
|
||||
p = strchr(pp + strlen(pp) - USTAR_name_size - 1, '/');
|
||||
/*
|
||||
* If the separator we found is the first '/', find
|
||||
* the next one. (This is a pathological case that
|
||||
* occurs for paths of exactly 101 bytes that start with
|
||||
* '/'; it occurs because the separating '/' is not
|
||||
* stored explicitly and the reconstruction assumes that
|
||||
* an empty prefix means there is no '/' separator.)
|
||||
*/
|
||||
if (p == pp)
|
||||
p = strchr(p + 1, '/');
|
||||
/*
|
||||
* If there is no path separator, or the prefix or
|
||||
* remaining name are too large, return an error.
|
||||
|
@ -31,8 +31,8 @@ __FBSDID("$FreeBSD$");
|
||||
* filenames into prefix/suffix.
|
||||
*/
|
||||
|
||||
static void
|
||||
test_filename(int dlen, int flen)
|
||||
static
|
||||
test_filename(const char *prefix, int dlen, int flen)
|
||||
{
|
||||
char buff[8192];
|
||||
char filename[400];
|
||||
@ -40,12 +40,17 @@ test_filename(int dlen, int flen)
|
||||
struct archive_entry *ae;
|
||||
struct archive *a;
|
||||
size_t used;
|
||||
int i;
|
||||
size_t prefix_length = 0;
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; i < dlen; i++)
|
||||
if (prefix) {
|
||||
strcpy(filename, prefix);
|
||||
i = prefix_length = strlen(prefix);
|
||||
}
|
||||
for (; i < prefix_length + dlen; i++)
|
||||
filename[i] = 'a';
|
||||
filename[i++] = '/';
|
||||
for (; i < dlen + flen + 1; i++)
|
||||
for (; i < prefix_length + dlen + flen + 1; i++)
|
||||
filename[i] = 'b';
|
||||
filename[i++] = '\0';
|
||||
|
||||
@ -111,7 +116,7 @@ test_filename(int dlen, int flen)
|
||||
assertA(0 == archive_read_next_header(a, &ae));
|
||||
failure("Pathname %d/%d: %s", dlen, flen, archive_entry_pathname(ae));
|
||||
assertEqualString(filename, archive_entry_pathname(ae));
|
||||
assert((S_IFREG | 0755) == archive_entry_mode(ae));
|
||||
assertEqualInt((S_IFREG | 0755), archive_entry_mode(ae));
|
||||
|
||||
/*
|
||||
* Read the two dirs and check the names.
|
||||
@ -147,13 +152,15 @@ DEFINE_TEST(test_tar_filenames)
|
||||
/* Repeat the following for a variety of dir/file lengths. */
|
||||
for (dlen = 40; dlen < 60; dlen++) {
|
||||
for (flen = 40; flen < 60; flen++) {
|
||||
test_filename(dlen, flen);
|
||||
test_filename(NULL, dlen, flen);
|
||||
test_filename("/", dlen, flen);
|
||||
}
|
||||
}
|
||||
|
||||
for (dlen = 140; dlen < 160; dlen++) {
|
||||
for (flen = 90; flen < 110; flen++) {
|
||||
test_filename(dlen, flen);
|
||||
test_filename(NULL, dlen, flen);
|
||||
test_filename("/", dlen, flen);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user