Assume directory members have size=0.

Since commit b8d8a61b, tar started honoring size field in headers
of the directory archive members when listing and extracting. That
doesn't seem right: although GNU tar always stores 0 for such members,
there are other tar implementation that don't. As a result, GNU tar
skips the actual directory contents when listing or extracting archives
created by such implementations.

This commit fixes that by assuming that size is 0 for directory archive
members.

* src/list.c (member_is_dir): Restore function.
(skim_member): Don't apply skim_file to directory members.
* tests/skipdir.at: Fix expectations.
This commit is contained in:
Sergey Poznyakoff
2026-07-23 10:52:03 +03:00
parent 5a225f25c5
commit 19a3a73e8c
2 changed files with 25 additions and 2 deletions
+20 -1
View File
@@ -1437,6 +1437,24 @@ skip_member (void)
skim_member (false);
}
static bool
member_is_dir (struct tar_stat_info *info, char typeflag)
{
switch (typeflag)
{
case AREGTYPE:
case REGTYPE:
case CONTTYPE:
return info->had_trailing_slash;
case DIRTYPE:
return true;
default:
return false;
}
}
/* Skip the current member in the archive.
If MUST_COPY, always copy instead of skipping. */
void
@@ -1450,7 +1468,8 @@ skim_member (bool must_copy)
if (current_stat_info.is_sparse)
sparse_skim_file (&current_stat_info, must_copy);
else
else if (!member_is_dir (&current_stat_info,
current_header->header.typeflag))
skim_file (current_stat_info.stat.st_size, must_copy);
mv_end ();
+5 -1
View File
@@ -42,11 +42,15 @@ base64 -d < archive.in | xz -c -d > archive.tar
AT_CHECK([tar tf archive.tar],
[0],
[owo1/
owo2/
])
AT_CHECK([tar vxf archive.tar],
[0],
[owo1/
owo2/
])
AT_CHECK([tar -xvf archive.tar --exclude owo1],
[0])
[0],
[owo2/
])
AT_CLEANUP