aboutsummaryrefslogtreecommitdiff
path: root/archival/libunarchive
diff options
context:
space:
mode:
Diffstat (limited to 'archival/libunarchive')
-rw-r--r--archival/libunarchive/filter_accept_list_reassign.c20
-rw-r--r--archival/libunarchive/get_header_ar.c5
-rw-r--r--archival/libunarchive/get_header_tar.c27
-rw-r--r--archival/libunarchive/get_header_tar_gz.c1
-rw-r--r--archival/libunarchive/unpack_ar_archive.c3
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;
}