diff options
author | Denys Vlasenko | 2016-11-11 17:56:45 +0100 |
---|---|---|
committer | Denys Vlasenko | 2016-11-11 17:56:45 +0100 |
commit | 9655f95d0f501b03b33c7896b7b0c23d090aff81 (patch) | |
tree | 66ea6ffe5d8a5791b7bb8fcb8b7eebaceea5d96e /archival/libarchive | |
parent | 87e039d0160be16a9a242f74af2e90cdb9f97e12 (diff) | |
download | busybox-9655f95d0f501b03b33c7896b7b0c23d090aff81.zip busybox-9655f95d0f501b03b33c7896b7b0c23d090aff81.tar.gz |
tar: handle pax-encoded utf8 filenames and link names. Closes 9406
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'archival/libarchive')
-rw-r--r-- | archival/libarchive/get_header_tar.c | 32 |
1 files changed, 25 insertions, 7 deletions
diff --git a/archival/libarchive/get_header_tar.c b/archival/libarchive/get_header_tar.c index ea91a88..c7e3bc1 100644 --- a/archival/libarchive/get_header_tar.c +++ b/archival/libarchive/get_header_tar.c @@ -113,11 +113,19 @@ static void process_pax_hdr(archive_handle_t *archive_handle, unsigned sz, int g value = end + 1; # if ENABLE_FEATURE_TAR_GNU_EXTENSIONS - if (!global && is_prefixed_with(value, "path=")) { - value += sizeof("path=") - 1; - free(archive_handle->tar__longname); - archive_handle->tar__longname = xstrdup(value); - continue; + if (!global) { + if (is_prefixed_with(value, "path=")) { + value += sizeof("path=") - 1; + free(archive_handle->tar__longname); + archive_handle->tar__longname = xstrdup(value); + continue; + } + if (is_prefixed_with(value, "linkpath=")) { + value += sizeof("linkpath=") - 1; + free(archive_handle->tar__linkname); + archive_handle->tar__linkname = xstrdup(value); + continue; + } } # endif @@ -179,7 +187,13 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle) * the message and we don't check whether we indeed * saw zero block directly before this. */ if (i == 0) { - bb_error_msg("short read"); + /* GNU tar 1.29 will be silent if tar archive ends abruptly + * (if there are no zero blocks at all, and last read returns zero, + * not short read 0 < len < 512). Complain only if + * the very first read fails. Grrr. + */ + if (archive_handle->offset == 0) + bb_error_msg("short read"); /* this merely signals end of archive, not exit(1): */ return EXIT_FAILURE; } @@ -195,7 +209,11 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle) archive_handle->offset += i; /* If there is no filename its an empty header */ - if (tar.name[0] == 0 && tar.prefix[0] == 0) { + if (tar.name[0] == 0 && tar.prefix[0] == 0 + /* Have seen a tar archive with pax 'x' header supplying UTF8 filename, + * with actual file having all name fields NUL-filled. Check this: */ + && !p_longname + ) { if (archive_handle->tar__end) { /* Second consecutive empty header - end of archive. * Read until the end to empty the pipe from gz or bz2 |