René Scharfe <rene.scharfe@xxxxxxxxxxxxxx> writes: > The name field of a tar header has a size of 100 characters. This limit > was extended long ago in a backward compatible way by providing the > additional prefix field, which can hold 155 additional characters. The > actual path is constructed at extraction time by concatenating the prefix > field, a slash and the name field. > > get_path_prefix() is used to determine which slash in the path is used as > the cutting point and thus which part of it is placed into the field > prefix and which into the field name. It tries to cram as much into the > prefix field as possible. (And only if we can't fit a path into the > provided 255 characters we use a pax extended header to store it.) > > If a path is longer than 100 but shorter than 156 characters and ends > with a slash (i.e. is for a directory) then get_path_prefix() puts the > whole path in the prefix field and leaves the name field empty. GNU tar > reconstructs the path without complaint, but the tar included with > NetBSD 6 does not: It reports the header to be invalid. > > For compatibility with this version of tar, make sure to never leave the > name field empty. In order to do that, trim the trailing slash from the > part considered as possible prefix, if it exists -- that way the last > path component (or more, but not less) will end up in the name field. Nicely explained; thanks. Makes me wonder what we should do for a file inside a directory whose name is 10 bytes long, and whose filename is 120 bytes long, though. Sounds like people on NetBSD are SOL due to the 155+'/'+100 in such a case and there is nothing we can do, I guess. > Signed-off-by: Rene Scharfe <rene.scharfe@xxxxxxxxxxxxxx> > --- > archive-tar.c | 2 ++ > 1 file changed, 2 insertions(+) > > diff --git a/archive-tar.c b/archive-tar.c > index 0ba3f25..923daf5 100644 > --- a/archive-tar.c > +++ b/archive-tar.c > @@ -153,6 +153,8 @@ static unsigned int ustar_header_chksum(const struct ustar_header *header) > static size_t get_path_prefix(const char *path, size_t pathlen, size_t maxlen) > { > size_t i = pathlen; > + if (i > 1 && path[i - 1] == '/') > + i--; > if (i > maxlen) > i = maxlen; > do { -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html