diff options
Diffstat (limited to 'archival/libunarchive')
-rw-r--r-- | archival/libunarchive/filter_accept_list_reassign.c | 20 | ||||
-rw-r--r-- | archival/libunarchive/get_header_ar.c | 5 | ||||
-rw-r--r-- | archival/libunarchive/get_header_tar.c | 27 | ||||
-rw-r--r-- | archival/libunarchive/get_header_tar_gz.c | 1 | ||||
-rw-r--r-- | archival/libunarchive/unpack_ar_archive.c | 3 |
5 files changed, 37 insertions, 19 deletions
diff --git a/archival/libunarchive/filter_accept_list_reassign.c b/archival/libunarchive/filter_accept_list_reassign.c index 4f2d4cde5..4dbc2d13e 100644 --- a/archival/libunarchive/filter_accept_list_reassign.c +++ b/archival/libunarchive/filter_accept_list_reassign.c @@ -8,6 +8,8 @@ #include "libbb.h" #include "unarchive.h" +/* Built and used only if ENABLE_DPKG || ENABLE_DPKG_DEB */ + /* * Reassign the subarchive metadata parser based on the filename extension * e.g. if its a .tar.gz modify archive_handle->sub_archive to process a .tar.gz @@ -19,23 +21,25 @@ char FAST_FUNC filter_accept_list_reassign(archive_handle_t *archive_handle) if (find_list_entry(archive_handle->accept, archive_handle->file_header->name)) { const char *name_ptr; - /* Extract the last 2 extensions */ + /* Find extension */ name_ptr = strrchr(archive_handle->file_header->name, '.'); /* Modify the subarchive handler based on the extension */ -#if ENABLE_FEATURE_DEB_TAR_GZ - if (strcmp(name_ptr, ".gz") == 0) { + if (ENABLE_FEATURE_DEB_TAR_GZ + && strcmp(name_ptr, ".gz") == 0 + ) { archive_handle->action_data_subarchive = get_header_tar_gz; return EXIT_SUCCESS; } -#endif -#if ENABLE_FEATURE_DEB_TAR_BZ2 - if (strcmp(name_ptr, ".bz2") == 0) { + if (ENABLE_FEATURE_DEB_TAR_BZ2 + && strcmp(name_ptr, ".bz2") == 0 + ) { archive_handle->action_data_subarchive = get_header_tar_bz2; return EXIT_SUCCESS; } -#endif - if (ENABLE_FEATURE_DEB_TAR_LZMA && !strcmp(name_ptr, ".lzma")) { + if (ENABLE_FEATURE_DEB_TAR_LZMA + && strcmp(name_ptr, ".lzma") == 0 + ) { archive_handle->action_data_subarchive = get_header_tar_lzma; return EXIT_SUCCESS; } diff --git a/archival/libunarchive/get_header_ar.c b/archival/libunarchive/get_header_ar.c index 59fd34c73..d476a9d24 100644 --- a/archival/libunarchive/get_header_ar.c +++ b/archival/libunarchive/get_header_ar.c @@ -108,12 +108,13 @@ char FAST_FUNC get_header_ar(archive_handle_t *archive_handle) if (archive_handle->filter(archive_handle) == EXIT_SUCCESS) { archive_handle->action_header(typed); +#if ENABLE_DPKG || ENABLE_DPKG_DEB if (archive_handle->sub_archive) { while (archive_handle->action_data_subarchive(archive_handle->sub_archive) == EXIT_SUCCESS) continue; - } else { + } else +#endif archive_handle->action_data(archive_handle); - } } else { data_skip(archive_handle); } diff --git a/archival/libunarchive/get_header_tar.c b/archival/libunarchive/get_header_tar.c index 69362f1cc..cf35d41a0 100644 --- a/archival/libunarchive/get_header_tar.c +++ b/archival/libunarchive/get_header_tar.c @@ -92,22 +92,32 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle) again_after_align: #if ENABLE_DESKTOP + /* to prevent misdetection of bz2 sig */ + *(uint32_t*)(&tar) = 0; i = full_read(archive_handle->src_fd, &tar, 512); /* If GNU tar sees EOF in above read, it says: * "tar: A lone zero block at N", where N = kilobyte * where EOF was met (not EOF block, actual EOF!), - * and tar will exit with error code 0. + * and exits with EXIT_SUCCESS. * We will mimic exit(EXIT_SUCCESS), although we will not mimic * the message and we don't check whether we indeed * saw zero block directly before this. */ - if (i == 0) + if (i == 0) { xfunc_error_retval = 0; - if (i != 512) + short_read: bb_error_msg_and_die("short read"); + } + if (i != 512) { + if (ENABLE_FEATURE_TAR_AUTODETECT) + goto autodetect; + goto short_read; + } + #else - xread(archive_handle->src_fd, &tar, 512); + i = 512; + xread(archive_handle->src_fd, &tar, i); #endif - archive_handle->offset += 512; + archive_handle->offset += i; /* If there is no filename its an empty header */ if (tar.name[0] == 0 && tar.prefix[0] == 0) { @@ -133,6 +143,7 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle) #if ENABLE_FEATURE_TAR_AUTODETECT char FAST_FUNC (*get_header_ptr)(archive_handle_t *); + USE_DESKTOP(autodetect:) /* tar gz/bz autodetect: check for gz/bz2 magic. * If we see the magic, and it is the very first block, * we can switch to get_header_tar_gz/bz2/lzma(). @@ -154,7 +165,7 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle) /* Two different causes for lseek() != 0: * unseekable fd (would like to support that too, but...), * or not first block (false positive, it's not .gz/.bz2!) */ - if (lseek(archive_handle->src_fd, -512, SEEK_CUR) != 0) + if (lseek(archive_handle->src_fd, -i, SEEK_CUR) != 0) goto err; while (get_header_ptr(archive_handle) == EXIT_SUCCESS) continue; @@ -328,7 +339,7 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle) p_linkname = NULL; } #endif - if (!strncmp(file_header->name, "/../"+1, 3) + if (strncmp(file_header->name, "/../"+1, 3) == 0 || strstr(file_header->name, "/../") ) { bb_error_msg_and_die("name with '..' encountered: '%s'", @@ -340,7 +351,7 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle) cp = last_char_is(file_header->name, '/'); if (archive_handle->filter(archive_handle) == EXIT_SUCCESS) { - archive_handle->action_header(archive_handle->file_header); + archive_handle->action_header(/*archive_handle->*/ file_header); /* Note that we kill the '/' only after action_header() */ /* (like GNU tar 1.15.1: verbose mode outputs "dir/dir/") */ if (cp) *cp = '\0'; diff --git a/archival/libunarchive/get_header_tar_gz.c b/archival/libunarchive/get_header_tar_gz.c index 086c6df42..e88b720a8 100644 --- a/archival/libunarchive/get_header_tar_gz.c +++ b/archival/libunarchive/get_header_tar_gz.c @@ -20,6 +20,7 @@ char FAST_FUNC get_header_tar_gz(archive_handle_t *archive_handle) * need the header. */ #if BB_MMU xread(archive_handle->src_fd, &magic, 2); + /* Can skip this check, but error message will be less clear */ if ((magic[0] != 0x1f) || (magic[1] != 0x8b)) { bb_error_msg_and_die("invalid gzip magic"); } diff --git a/archival/libunarchive/unpack_ar_archive.c b/archival/libunarchive/unpack_ar_archive.c index 9c2f68b14..dc2eec223 100644 --- a/archival/libunarchive/unpack_ar_archive.c +++ b/archival/libunarchive/unpack_ar_archive.c @@ -16,5 +16,6 @@ void FAST_FUNC unpack_ar_archive(archive_handle_t *ar_archive) } ar_archive->offset += 7; - while (get_header_ar(ar_archive) == EXIT_SUCCESS); + while (get_header_ar(ar_archive) == EXIT_SUCCESS) + continue; } |