busybox: Backport fix for unzip
authorFredrik Fornwall <fredrik@fornwall.net>
Fri, 29 Apr 2016 02:34:43 +0000 (04:34 +0200)
committerFredrik Fornwall <fredrik@fornwall.net>
Fri, 29 Apr 2016 02:34:43 +0000 (04:34 +0200)
packages/busybox/build.sh
packages/busybox/unzip.c.patch [new file with mode: 0644]

index 2ceb027..dce90ed 100755 (executable)
@@ -2,6 +2,7 @@ TERMUX_PKG_HOMEPAGE=http://www.busybox.net/
 TERMUX_PKG_DESCRIPTION="Tiny versions of many common UNIX utilities into a single small executable"
 TERMUX_PKG_ESSENTIAL=yes
 TERMUX_PKG_VERSION=1.24.2
+TERMUX_PKG_BUILD_REVISION=1
 TERMUX_PKG_SRCURL=http://www.busybox.net/downloads/busybox-${TERMUX_PKG_VERSION}.tar.bz2
 TERMUX_PKG_BUILD_IN_SRC=yes
 
diff --git a/packages/busybox/unzip.c.patch b/packages/busybox/unzip.c.patch
new file mode 100644 (file)
index 0000000..1b587a0
--- /dev/null
@@ -0,0 +1,112 @@
+Backport of commit:
+  https://git.busybox.net/busybox/commit/?id=0ccf52a9fb9fa2f76eacbb6f1ef8419220557a40
+for issue:
+  https://bugs.busybox.net/show_bug.cgi?id=8821
+
+diff --git a/archival/unzip.c b/archival/unzip.c
+index f41ab6f..b0a6ca8 100644
+--- a/archival/unzip.c
++++ b/archival/unzip.c
+@@ -45,6 +45,12 @@
+ #include "libbb.h"
+ #include "bb_archive.h"
++#if 0
++# define dbg(...) bb_error_msg(__VA_ARGS__)
++#else
++# define dbg(...) ((void)0)
++#endif
++
+ enum {
+ #if BB_BIG_ENDIAN
+       ZIP_FILEHEADER_MAGIC = 0x504b0304,
+@@ -193,15 +199,17 @@ static uint32_t find_cdf_offset(void)
+       unsigned char *p;
+       off_t end;
+       unsigned char *buf = xzalloc(PEEK_FROM_END);
++      uint32_t found;
+       end = xlseek(zip_fd, 0, SEEK_END);
+       end -= PEEK_FROM_END;
+       if (end < 0)
+               end = 0;
+-      xlseek(zip_fd, end, SEEK_SET);
++      dbg("Looking for cdf_offset starting from 0x%"OFF_FMT"x", end);
++      xlseek(zip_fd, end, SEEK_SET);
+       full_read(zip_fd, buf, PEEK_FROM_END);
+-      cde_header.formatted.cdf_offset = BAD_CDF_OFFSET;
++      found = BAD_CDF_OFFSET;
+       p = buf;
+       while (p <= buf + PEEK_FROM_END - CDE_HEADER_LEN - 4) {
+               if (*p != 'P') {
+@@ -220,14 +228,25 @@ static uint32_t find_cdf_offset(void)
+               /*
+                * I've seen .ZIP files with seemingly valid CDEs
+                * where cdf_offset points past EOF - ??
+-               * Ignore such CDEs:
++               * This check ignores such CDEs:
+                */
+-              if (cde_header.formatted.cdf_offset < end + (p - buf))
+-                      break;
+-              cde_header.formatted.cdf_offset = BAD_CDF_OFFSET;
++              if (cde_header.formatted.cdf_offset < end + (p - buf)) {
++                      found = cde_header.formatted.cdf_offset;
++                      dbg("Possible cdf_offset:0x%x at 0x%"OFF_FMT"x",
++                              (unsigned)found, end + (p-3 - buf));
++                      dbg("  cdf_offset+cdf_size:0x%x",
++                              (unsigned)(found + SWAP_LE32(cde_header.formatted.cdf_size)));
++                      /*
++                       * We do not "break" here because only the last CDE is valid.
++                       * I've seen a .zip archive which contained a .zip file,
++                       * uncompressed, and taking the first CDE was using
++                       * the CDE inside that file!
++                       */
++              }
+       }
+       free(buf);
+-      return cde_header.formatted.cdf_offset;
++      dbg("Found cdf_offset:0x%x", (unsigned)found);
++      return found;
+ };
+ static uint32_t read_next_cdf(uint32_t cdf_offset, cdf_header_t *cdf_ptr)
+@@ -240,9 +259,13 @@ static uint32_t read_next_cdf(uint32_t cdf_offset, cdf_header_t *cdf_ptr)
+               cdf_offset = find_cdf_offset();
+       if (cdf_offset != BAD_CDF_OFFSET) {
++              dbg("Reading CDF at 0x%x", (unsigned)cdf_offset);
+               xlseek(zip_fd, cdf_offset + 4, SEEK_SET);
+               xread(zip_fd, cdf_ptr->raw, CDF_HEADER_LEN);
+               FIX_ENDIANNESS_CDF(*cdf_ptr);
++              dbg("file_name_length:%u", (unsigned)cdf_ptr->formatted.file_name_length);
++              dbg("extra_field_length:%u", (unsigned)cdf_ptr->formatted.extra_field_length);
++              dbg("file_comment_length:%u", (unsigned)cdf_ptr->formatted.file_comment_length);
+               cdf_offset += 4 + CDF_HEADER_LEN
+                       + cdf_ptr->formatted.file_name_length
+                       + cdf_ptr->formatted.extra_field_length
+@@ -532,11 +555,14 @@ int unzip_main(int argc, char **argv)
+               /* Check magic number */
+               xread(zip_fd, &magic, 4);
+               /* Central directory? It's at the end, so exit */
+-              if (magic == ZIP_CDF_MAGIC)
++              if (magic == ZIP_CDF_MAGIC) {
++                      dbg("got ZIP_CDF_MAGIC");
+                       break;
++              }
+ #if ENABLE_DESKTOP
+               /* Data descriptor? It was a streaming file, go on */
+               if (magic == ZIP_DD_MAGIC) {
++                      dbg("got ZIP_DD_MAGIC");
+                       /* skip over duplicate crc32, cmpsize and ucmpsize */
+                       unzip_skip(3 * 4);
+                       continue;
+@@ -544,6 +570,7 @@ int unzip_main(int argc, char **argv)
+ #endif
+               if (magic != ZIP_FILEHEADER_MAGIC)
+                       bb_error_msg_and_die("invalid zip magic %08X", (int)magic);
++              dbg("got ZIP_FILEHEADER_MAGIC");
+               /* Read the file header */
+               xread(zip_fd, zip_header.raw, ZIP_HEADER_LEN);
+