Re: [PATCH] archive-tar: split long paths more carefully
- From
Junio C Hamano <gitster@pobox.com>
- Date
- Jan 6, 2013, 06:54 UTC
- Message-ID
- <7v7gnqpzrz.fsf@alter.siamese.dyndns.org>
- In-Reply-To
- <50E8AE12.8040102@lsrfire.ath.cx>
René Scharfe <rene.scharfe@lsrfire.ath.cx> writes:
Show 22 quoted lines
> 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.
Show 18 quoted lines
> Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>
> ---
> 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 {