Browse Source

initial package creation

Signed-off-by: Toshaan Bharvani <toshaan@powerel.org>
master
Toshaan Bharvani 2 years ago
commit
7736687e84
  1. 39
      SOURCES/0001-Fix-CVE-2016-9844-rhbz-1404283.patch
  2. 131
      SOURCES/unzip-6.0-COVSCAN-fix-unterminated-string.patch
  3. 381
      SOURCES/unzip-6.0-alt-iconv-utf8-print.patch
  4. 398
      SOURCES/unzip-6.0-alt-iconv-utf8.patch
  5. 12
      SOURCES/unzip-6.0-attribs-overflow.patch
  6. 30
      SOURCES/unzip-6.0-bzip2-configure.patch
  7. 131
      SOURCES/unzip-6.0-caseinsensitive.patch
  8. 176
      SOURCES/unzip-6.0-close.patch
  9. 12
      SOURCES/unzip-6.0-configure.patch
  10. 79
      SOURCES/unzip-6.0-cve-2014-8139.patch
  11. 25
      SOURCES/unzip-6.0-cve-2014-8140.patch
  12. 138
      SOURCES/unzip-6.0-cve-2014-8141.patch
  13. 34
      SOURCES/unzip-6.0-cve-2018-1000035-heap-based-overflow.patch
  14. 35
      SOURCES/unzip-6.0-cve-2018-18384.patch
  15. 10
      SOURCES/unzip-6.0-exec-shield.patch
  16. 477
      SOURCES/unzip-6.0-fix-recmatch.patch
  17. 90
      SOURCES/unzip-6.0-format-secure.patch
  18. 104
      SOURCES/unzip-6.0-heap-overflow-infloop.patch
  19. 11
      SOURCES/unzip-6.0-manpage-fix.patch
  20. 34
      SOURCES/unzip-6.0-overflow-long-fsize.patch
  21. 25
      SOURCES/unzip-6.0-overflow.patch
  22. 17
      SOURCES/unzip-6.0-symlink.patch
  23. 41
      SOURCES/unzip-6.0-timestamp.patch
  24. 26
      SOURCES/unzip-6.0-valgrind.patch
  25. 28
      SOURCES/unzip-6.0-x-option.patch
  26. 25
      SOURCES/unzip-zipbomb-manpage.patch
  27. 25
      SOURCES/unzip-zipbomb-part1.patch
  28. 349
      SOURCES/unzip-zipbomb-part2.patch
  29. 112
      SOURCES/unzip-zipbomb-part3.patch
  30. 25
      SOURCES/unzip-zipbomb-part4.patch
  31. 26
      SOURCES/unzip-zipbomb-part5.patch
  32. 95
      SOURCES/unzip-zipbomb-part6.patch
  33. 200
      SOURCES/unzip-zipbomb-switch.patch
  34. 632
      SPECS/unzip.spec

39
SOURCES/0001-Fix-CVE-2016-9844-rhbz-1404283.patch

@ -0,0 +1,39 @@
From 754137e70cf58a64ad524b704a86b651ba0cde07 Mon Sep 17 00:00:00 2001
From: Petr Stodulka <pstodulk@redhat.com>
Date: Wed, 14 Dec 2016 16:30:36 +0100
Subject: [PATCH] Fix CVE-2016-9844 (rhbz#1404283)

Fixes buffer overflow in zipinfo in similar way like fix for
CVE-2014-9913 provided by upstream.
---
zipinfo.c | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/zipinfo.c b/zipinfo.c
index c03620e..accca2a 100644
--- a/zipinfo.c
+++ b/zipinfo.c
@@ -1984,7 +1984,19 @@ static int zi_short(__G) /* return PK-type error code */
ush dnum=(ush)((G.crec.general_purpose_bit_flag>>1) & 3);
methbuf[3] = dtype[dnum];
} else if (methnum >= NUM_METHODS) { /* unknown */
- sprintf(&methbuf[1], "%03u", G.crec.compression_method);
+ /* 2016-12-05 SMS.
+ * https://launchpad.net/bugs/1643750
+ * Unexpectedly large compression methods overflow
+ * &methbuf[]. Use the old, three-digit decimal format
+ * for values which fit. Otherwise, sacrifice the "u",
+ * and use four-digit hexadecimal.
+ */
+ if (G.crec.compression_method <= 999) {
+ sprintf( &methbuf[ 1], "%03u", G.crec.compression_method);
+ } else {
+ sprintf( &methbuf[ 0], "%04X", G.crec.compression_method);
+ }
+
}
for (k = 0; k < 15; ++k)
--
2.5.5

131
SOURCES/unzip-6.0-COVSCAN-fix-unterminated-string.patch

@ -0,0 +1,131 @@
From 06d1b08aef94984256cad3c5a54cedb10295681f Mon Sep 17 00:00:00 2001
From: Jakub Martisko <jamartis@redhat.com>
Date: Thu, 8 Nov 2018 09:31:18 +0100
Subject: [PATCH] Possible unterminated string fix

---
unix/unix.c | 4 +++-
unix/unxcfg.h | 2 +-
unzip.c | 12 ++++++++----
zipinfo.c | 12 ++++++++----
4 files changed, 20 insertions(+), 10 deletions(-)

diff --git a/unix/unix.c b/unix/unix.c
index 59b622d..cd57f80 100644
--- a/unix/unix.c
+++ b/unix/unix.c
@@ -1945,7 +1945,9 @@ void init_conversion_charsets()
for(i = 0; i < sizeof(dos_charset_map)/sizeof(CHARSET_MAP); i++)
if(!strcasecmp(local_charset, dos_charset_map[i].local_charset)) {
strncpy(OEM_CP, dos_charset_map[i].archive_charset,
- sizeof(OEM_CP));
+ MAX_CP_NAME - 1);
+
+ OEM_CP[MAX_CP_NAME - 1] = '\0';
break;
}
}
diff --git a/unix/unxcfg.h b/unix/unxcfg.h
index 8729de2..9ee8cfe 100644
--- a/unix/unxcfg.h
+++ b/unix/unxcfg.h
@@ -228,7 +228,7 @@ typedef struct stat z_stat;
/* and notfirstcall are used by do_wild(). */
-#define MAX_CP_NAME 25
+#define MAX_CP_NAME 25 + 1
#ifdef SETLOCALE
# undef SETLOCALE
diff --git a/unzip.c b/unzip.c
index 2d94a38..a485f2b 100644
--- a/unzip.c
+++ b/unzip.c
@@ -1561,7 +1561,8 @@ int uz_opts(__G__ pargc, pargv)
"error: a valid character encoding should follow the -I argument"));
return(PK_PARAM);
}
- strncpy(ISO_CP, s, sizeof(ISO_CP));
+ strncpy(ISO_CP, s, MAX_CP_NAME - 1);
+ ISO_CP[MAX_CP_NAME - 1] = '\0';
} else { /* -I charset */
++argv;
if(!(--argc > 0 && *argv != NULL && **argv != '-')) {
@@ -1570,7 +1571,8 @@ int uz_opts(__G__ pargc, pargv)
return(PK_PARAM);
}
s = *argv;
- strncpy(ISO_CP, s, sizeof(ISO_CP));
+ strncpy(ISO_CP, s, MAX_CP_NAME - 1);
+ ISO_CP[MAX_CP_NAME - 1] = '\0';
}
while(*(++s)); /* No params straight after charset name */
}
@@ -1665,7 +1667,8 @@ int uz_opts(__G__ pargc, pargv)
"error: a valid character encoding should follow the -I argument"));
return(PK_PARAM);
}
- strncpy(OEM_CP, s, sizeof(OEM_CP));
+ strncpy(OEM_CP, s, MAX_CP_NAME - 1);
+ OEM_CP[MAX_CP_NAME - 1] = '\0';
} else { /* -O charset */
++argv;
if(!(--argc > 0 && *argv != NULL && **argv != '-')) {
@@ -1674,7 +1677,8 @@ int uz_opts(__G__ pargc, pargv)
return(PK_PARAM);
}
s = *argv;
- strncpy(OEM_CP, s, sizeof(OEM_CP));
+ strncpy(OEM_CP, s, MAX_CP_NAME - 1);
+ OEM_CP[MAX_CP_NAME - 1] = '\0';
}
while(*(++s)); /* No params straight after charset name */
}
diff --git a/zipinfo.c b/zipinfo.c
index accca2a..cb7e08d 100644
--- a/zipinfo.c
+++ b/zipinfo.c
@@ -519,7 +519,8 @@ int zi_opts(__G__ pargc, pargv)
"error: a valid character encoding should follow the -I argument"));
return(PK_PARAM);
}
- strncpy(ISO_CP, s, sizeof(ISO_CP));
+ strncpy(ISO_CP, s, MAX_CP_NAME - 1);
+ ISO_CP[MAX_CP_NAME - 1] = '\0';
} else { /* -I charset */
++argv;
if(!(--argc > 0 && *argv != NULL && **argv != '-')) {
@@ -528,7 +529,8 @@ int zi_opts(__G__ pargc, pargv)
return(PK_PARAM);
}
s = *argv;
- strncpy(ISO_CP, s, sizeof(ISO_CP));
+ strncpy(ISO_CP, s, MAX_CP_NAME - 1);
+ ISO_CP[MAX_CP_NAME - 1] = '\0';
}
while(*(++s)); /* No params straight after charset name */
}
@@ -568,7 +570,8 @@ int zi_opts(__G__ pargc, pargv)
"error: a valid character encoding should follow the -I argument"));
return(PK_PARAM);
}
- strncpy(OEM_CP, s, sizeof(OEM_CP));
+ strncpy(OEM_CP, s, MAX_CP_NAME - 1);
+ OEM_CP[MAX_CP_NAME - 1] = '\0';
} else { /* -O charset */
++argv;
if(!(--argc > 0 && *argv != NULL && **argv != '-')) {
@@ -577,7 +580,8 @@ int zi_opts(__G__ pargc, pargv)
return(PK_PARAM);
}
s = *argv;
- strncpy(OEM_CP, s, sizeof(OEM_CP));
+ strncpy(OEM_CP, s, MAX_CP_NAME - 1);
+ OEM_CP[MAX_CP_NAME - 1] = '\0';
}
while(*(++s)); /* No params straight after charset name */
}
--
2.14.5

381
SOURCES/unzip-6.0-alt-iconv-utf8-print.patch

@ -0,0 +1,381 @@
From ca0212ba19b64488b9e8459a762c11ecd6e7d0bd Mon Sep 17 00:00:00 2001
From: Petr Stodulka <pstodulk@redhat.com>
Date: Tue, 24 Nov 2015 17:56:11 +0100
Subject: [PATCH] print correctly non-ascii filenames

---
extract.c | 289 ++++++++++++++++++++++++++++++++++++++++++++++++--------------
unzpriv.h | 7 ++
2 files changed, 233 insertions(+), 63 deletions(-)

diff --git a/extract.c b/extract.c
index 0ee4e93..741b7e0 100644
--- a/extract.c
+++ b/extract.c
@@ -2648,8 +2648,21 @@ static void set_deferred_symlink(__G__ slnk_entry)
} /* end function set_deferred_symlink() */
#endif /* SYMLINKS */
+/*
+ * If Unicode is supported, assume we have what we need to do this
+ * check using wide characters, avoiding MBCS issues.
+ */
-
+#ifndef UZ_FNFILTER_REPLACECHAR
+ /* A convenient choice for the replacement of unprintable char codes is
+ * the "single char wildcard", as this character is quite unlikely to
+ * appear in filenames by itself. The following default definition
+ * sets the replacement char to a question mark as the most common
+ * "single char wildcard"; this setting should be overridden in the
+ * appropiate system-specific configuration header when needed.
+ */
+# define UZ_FNFILTER_REPLACECHAR '?'
+#endif
/*************************/
/* Function fnfilter() */ /* here instead of in list.c for SFX */
@@ -2661,48 +2674,168 @@ char *fnfilter(raw, space, size) /* convert name to safely printable form */
extent size;
{
#ifndef NATIVE /* ASCII: filter ANSI escape codes, etc. */
- ZCONST uch *r=(ZCONST uch *)raw;
+ ZCONST uch *r; // =(ZCONST uch *)raw;
uch *s=space;
uch *slim=NULL;
uch *se=NULL;
int have_overflow = FALSE;
- if (size > 0) {
- slim = space + size
-#ifdef _MBCS
- - (MB_CUR_MAX - 1)
-#endif
- - 4;
+# if defined( UNICODE_SUPPORT) && defined( _MBCS)
+/* If Unicode support is enabled, and we have multi-byte characters,
+ * then do the isprint() checks by first converting to wide characters
+ * and checking those. This avoids our having to parse multi-byte
+ * characters for ourselves. After the wide-char replacements have been
+ * made, the wide string is converted back to the local character set.
+ */
+ wchar_t *wstring; /* wchar_t version of raw */
+ size_t wslen; /* length of wstring */
+ wchar_t *wostring; /* wchar_t version of output string */
+ size_t woslen; /* length of wostring */
+ char *newraw; /* new raw */
+
+ /* 2012-11-06 SMS.
+ * Changed to check the value returned by mbstowcs(), and bypass the
+ * Unicode processing if it fails. This seems to fix a problem
+ * reported in the SourceForge forum, but it's not clear that we
+ * should be doing any Unicode processing without some evidence that
+ * the name actually is Unicode. (Check bit 11 in the flags before
+ * coming here?)
+ * http://sourceforge.net/p/infozip/bugs/40/
+ */
+
+ if (MB_CUR_MAX <= 1)
+ {
+ /* There's no point to converting multi-byte chars if there are
+ * no multi-byte chars.
+ */
+ wslen = (size_t)-1;
}
- while (*r) {
- if (size > 0 && s >= slim && se == NULL) {
- se = s;
+ else
+ {
+ /* Get Unicode wide character count (for storage allocation). */
+ wslen = mbstowcs( NULL, raw, 0);
+ }
+
+ if (wslen != (size_t)-1)
+ {
+ /* Apparently valid Unicode. Allocate wide-char storage. */
+ wstring = (wchar_t *)malloc((wslen + 1) * sizeof(wchar_t));
+ if (wstring == NULL) {
+ strcpy( (char *)space, raw);
+ return (char *)space;
}
-#ifdef QDOS
- if (qlflag & 2) {
- if (*r == '/' || *r == '.') {
+ wostring = (wchar_t *)malloc(2 * (wslen + 1) * sizeof(wchar_t));
+ if (wostring == NULL) {
+ free(wstring);
+ strcpy( (char *)space, raw);
+ return (char *)space;
+ }
+
+ /* Convert the multi-byte Unicode to wide chars. */
+ wslen = mbstowcs(wstring, raw, wslen + 1);
+
+ /* Filter the wide-character string. */
+ fnfilterw( wstring, wostring, (2 * (wslen + 1) * sizeof(wchar_t)));
+
+ /* Convert filtered wide chars back to multi-byte. */
+ woslen = wcstombs( NULL, wostring, 0);
+ if ((newraw = malloc(woslen + 1)) == NULL) {
+ free(wstring);
+ free(wostring);
+ strcpy( (char *)space, raw);
+ return (char *)space;
+ }
+ woslen = wcstombs( newraw, wostring, (woslen * MB_CUR_MAX) + 1);
+
+ if (size > 0) {
+ slim = space + size - 4;
+ }
+ r = (ZCONST uch *)newraw;
+ while (*r) {
+ if (size > 0 && s >= slim && se == NULL) {
+ se = s;
+ }
+# ifdef QDOS
+ if (qlflag & 2) {
+ if (*r == '/' || *r == '.') {
+ if (se != NULL && (s > (space + (size-3)))) {
+ have_overflow = TRUE;
+ break;
+ }
+ ++r;
+ *s++ = '_';
+ continue;
+ }
+ } else
+# endif
+ {
if (se != NULL && (s > (space + (size-3)))) {
have_overflow = TRUE;
break;
}
- ++r;
- *s++ = '_';
- continue;
+ *s++ = *r++;
}
- } else
+ }
+ if (have_overflow) {
+ strcpy((char *)se, "...");
+ } else {
+ *s = '\0';
+ }
+
+ free(wstring);
+ free(wostring);
+ free(newraw);
+ }
+ else
+# endif /* defined( UNICODE_SUPPORT) && defined( _MBCS) */
+ {
+ /* No Unicode support, or apparently invalid Unicode. */
+ r = (ZCONST uch *)raw;
+
+ if (size > 0) {
+ slim = space + size
+#ifdef _MBCS
+ - (MB_CUR_MAX - 1)
+#endif
+ - 4;
+ }
+ while (*r) {
+ if (size > 0 && s >= slim && se == NULL) {
+ se = s;
+ }
+#ifdef QDOS
+ if (qlflag & 2) {
+ if (*r == '/' || *r == '.') {
+ if (se != NULL && (s > (space + (size-3)))) {
+ have_overflow = TRUE;
+ break;
+ }
+ ++r;
+ *s++ = '_';
+ continue;
+ }
+ } else
#endif
#ifdef HAVE_WORKING_ISPRINT
-# ifndef UZ_FNFILTER_REPLACECHAR
- /* A convenient choice for the replacement of unprintable char codes is
- * the "single char wildcard", as this character is quite unlikely to
- * appear in filenames by itself. The following default definition
- * sets the replacement char to a question mark as the most common
- * "single char wildcard"; this setting should be overridden in the
- * appropiate system-specific configuration header when needed.
- */
-# define UZ_FNFILTER_REPLACECHAR '?'
-# endif
- if (!isprint(*r)) {
+ if (!isprint(*r)) {
+ if (*r < 32) {
+ /* ASCII control codes are escaped as "^{letter}". */
+ if (se != NULL && (s > (space + (size-4)))) {
+ have_overflow = TRUE;
+ break;
+ }
+ *s++ = '^', *s++ = (uch)(64 + *r++);
+ } else {
+ /* Other unprintable codes are replaced by the
+ * placeholder character. */
+ if (se != NULL && (s > (space + (size-3)))) {
+ have_overflow = TRUE;
+ break;
+ }
+ *s++ = UZ_FNFILTER_REPLACECHAR;
+ INCSTR(r);
+ }
+#else /* !HAVE_WORKING_ISPRINT */
if (*r < 32) {
/* ASCII control codes are escaped as "^{letter}". */
if (se != NULL && (s > (space + (size-4)))) {
@@ -2710,47 +2843,30 @@ char *fnfilter(raw, space, size) /* convert name to safely printable form */
break;
}
*s++ = '^', *s++ = (uch)(64 + *r++);
+#endif /* ?HAVE_WORKING_ISPRINT */
} else {
- /* Other unprintable codes are replaced by the
- * placeholder character. */
+#ifdef _MBCS
+ unsigned i = CLEN(r);
+ if (se != NULL && (s > (space + (size-i-2)))) {
+ have_overflow = TRUE;
+ break;
+ }
+ for (; i > 0; i--)
+ *s++ = *r++;
+#else
if (se != NULL && (s > (space + (size-3)))) {
have_overflow = TRUE;
break;
}
- *s++ = UZ_FNFILTER_REPLACECHAR;
- INCSTR(r);
- }
-#else /* !HAVE_WORKING_ISPRINT */
- if (*r < 32) {
- /* ASCII control codes are escaped as "^{letter}". */
- if (se != NULL && (s > (space + (size-4)))) {
- have_overflow = TRUE;
- break;
- }
- *s++ = '^', *s++ = (uch)(64 + *r++);
-#endif /* ?HAVE_WORKING_ISPRINT */
- } else {
-#ifdef _MBCS
- unsigned i = CLEN(r);
- if (se != NULL && (s > (space + (size-i-2)))) {
- have_overflow = TRUE;
- break;
- }
- for (; i > 0; i--)
*s++ = *r++;
-#else
- if (se != NULL && (s > (space + (size-3)))) {
- have_overflow = TRUE;
- break;
- }
- *s++ = *r++;
#endif
- }
- }
- if (have_overflow) {
- strcpy((char *)se, "...");
- } else {
- *s = '\0';
+ }
+ }
+ if (have_overflow) {
+ strcpy((char *)se, "...");
+ } else {
+ *s = '\0';
+ }
}
#ifdef WINDLL
@@ -2772,6 +2888,53 @@ char *fnfilter(raw, space, size) /* convert name to safely printable form */
} /* end function fnfilter() */
+#if defined( UNICODE_SUPPORT) && defined( _MBCS)
+
+/****************************/
+/* Function fnfilter[w]() */ /* (Here instead of in list.c for SFX.) */
+/****************************/
+
+/* fnfilterw() - Convert wide name to safely printable form. */
+
+/* fnfilterw() - Convert wide-character name to safely printable form. */
+
+wchar_t *fnfilterw( src, dst, siz)
+ ZCONST wchar_t *src; /* Pointer to source char (string). */
+ wchar_t *dst; /* Pointer to destination char (string). */
+ extent siz; /* Not used (!). */
+{
+ wchar_t *dsx = dst;
+
+ /* Filter the wide chars. */
+ while (*src)
+ {
+ if (iswprint( *src))
+ {
+ /* Printable code. Copy it. */
+ *dst++ = *src;
+ }
+ else
+ {
+ /* Unprintable code. Substitute something printable for it. */
+ if (*src < 32)
+ {
+ /* Replace ASCII control code with "^{letter}". */
+ *dst++ = (wchar_t)'^';
+ *dst++ = (wchar_t)(64 + *src);
+ }
+ else
+ {
+ /* Replace other unprintable code with the placeholder. */
+ *dst++ = (wchar_t)UZ_FNFILTER_REPLACECHAR;
+ }
+ }
+ src++;
+ }
+ *dst = (wchar_t)0; /* NUL-terminate the destination string. */
+ return dsx;
+} /* fnfilterw(). */
+
+#endif /* defined( UNICODE_SUPPORT) && defined( _MBCS) */
#ifdef SET_DIR_ATTRIB
diff --git a/unzpriv.h b/unzpriv.h
index 22d3923..e48a652 100644
--- a/unzpriv.h
+++ b/unzpriv.h
@@ -1212,6 +1212,7 @@
# ifdef UNICODE_WCHAR
# if !(defined(_WIN32_WCE) || defined(POCKET_UNZIP))
# include <wchar.h>
+# include <wctype.h>
# endif
# endif
# ifndef _MBCS /* no need to include <locale.h> twice, see below */
@@ -2410,6 +2411,12 @@ int memflush OF((__GPRO__ ZCONST uch *rawbuf, ulg size));
char *fnfilter OF((ZCONST char *raw, uch *space,
extent size));
+# if defined( UNICODE_SUPPORT) && defined( _MBCS)
+wchar_t *fnfilterw OF((ZCONST wchar_t *src, wchar_t *dst,
+ extent siz));
+#endif
+
+
/*---------------------------------------------------------------------------
Decompression functions:
---------------------------------------------------------------------------*/
--
2.4.3

398
SOURCES/unzip-6.0-alt-iconv-utf8.patch

@ -0,0 +1,398 @@
From: Giovanni Scafora <giovanni.archlinux.org>
Subject: unzip files encoded with non-latin, non-unicode file names
Last-Update: 2015-02-11

Updated 2015-02-11 by Marc Deslauriers <marc.deslauriers@canonical.com>
to fix buffer overflow in charset_to_intern()

Index: unzip-6.0/unix/unix.c
===================================================================
--- unzip-6.0.orig/unix/unix.c 2015-02-11 08:46:43.675324290 -0500
+++ unzip-6.0/unix/unix.c 2015-02-11 09:18:04.902081319 -0500
@@ -30,6 +30,9 @@
#define UNZIP_INTERNAL
#include "unzip.h"
+#include <iconv.h>
+#include <langinfo.h>
+
#ifdef SCO_XENIX
# define SYSNDIR
#else /* SCO Unix, AIX, DNIX, TI SysV, Coherent 4.x, ... */
@@ -1874,3 +1877,102 @@
}
}
#endif /* QLZIP */
+
+
+typedef struct {
+ char *local_charset;
+ char *archive_charset;
+} CHARSET_MAP;
+
+/* A mapping of local <-> archive charsets used by default to convert filenames
+ * of DOS/Windows Zip archives. Currently very basic. */
+static CHARSET_MAP dos_charset_map[] = {
+ { "ANSI_X3.4-1968", "CP850" },
+ { "ISO-8859-1", "CP850" },
+ { "CP1252", "CP850" },
+ { "UTF-8", "CP866" },
+ { "KOI8-R", "CP866" },
+ { "KOI8-U", "CP866" },
+ { "ISO-8859-5", "CP866" }
+};
+
+char OEM_CP[MAX_CP_NAME] = "";
+char ISO_CP[MAX_CP_NAME] = "";
+
+/* Try to guess the default value of OEM_CP based on the current locale.
+ * ISO_CP is left alone for now. */
+void init_conversion_charsets()
+{
+ const char *local_charset;
+ int i;
+
+ /* Make a guess only if OEM_CP not already set. */
+ if(*OEM_CP == '\0') {
+ local_charset = nl_langinfo(CODESET);
+ for(i = 0; i < sizeof(dos_charset_map)/sizeof(CHARSET_MAP); i++)
+ if(!strcasecmp(local_charset, dos_charset_map[i].local_charset)) {
+ strncpy(OEM_CP, dos_charset_map[i].archive_charset,
+ sizeof(OEM_CP));
+ break;
+ }
+ }
+}
+
+/* Convert a string from one encoding to the current locale using iconv().
+ * Be as non-intrusive as possible. If error is encountered during covertion
+ * just leave the string intact. */
+static void charset_to_intern(char *string, char *from_charset)
+{
+ iconv_t cd;
+ char *s,*d, *buf;
+ size_t slen, dlen, buflen;
+ const char *local_charset;
+
+ if(*from_charset == '\0')
+ return;
+
+ buf = NULL;
+ local_charset = nl_langinfo(CODESET);
+
+ if((cd = iconv_open(local_charset, from_charset)) == (iconv_t)-1)
+ return;
+
+ slen = strlen(string);
+ s = string;
+
+ /* Make sure OUTBUFSIZ + 1 never ends up smaller than FILNAMSIZ
+ * as this function also gets called with G.outbuf in fileio.c
+ */
+ buflen = FILNAMSIZ;
+ if (OUTBUFSIZ + 1 < FILNAMSIZ)
+ {
+ buflen = OUTBUFSIZ + 1;
+ }
+
+ d = buf = malloc(buflen);
+ if(!d)
+ goto cleanup;
+
+ bzero(buf,buflen);
+ dlen = buflen - 1;
+
+ if(iconv(cd, &s, &slen, &d, &dlen) == (size_t)-1)
+ goto cleanup;
+ strncpy(string, buf, buflen);
+
+ cleanup:
+ free(buf);
+ iconv_close(cd);
+}
+
+/* Convert a string from OEM_CP to the current locale charset. */
+inline void oem_intern(char *string)
+{
+ charset_to_intern(string, OEM_CP);
+}
+
+/* Convert a string from ISO_CP to the current locale charset. */
+inline void iso_intern(char *string)
+{
+ charset_to_intern(string, ISO_CP);
+}
Index: unzip-6.0/unix/unxcfg.h
===================================================================
--- unzip-6.0.orig/unix/unxcfg.h 2015-02-11 08:46:43.675324290 -0500
+++ unzip-6.0/unix/unxcfg.h 2015-02-11 08:46:43.671324260 -0500
@@ -228,4 +228,30 @@
/* wild_dir, dirname, wildname, matchname[], dirnamelen, have_dirname, */
/* and notfirstcall are used by do_wild(). */
+
+#define MAX_CP_NAME 25
+
+#ifdef SETLOCALE
+# undef SETLOCALE
+#endif
+#define SETLOCALE(category, locale) setlocale(category, locale)
+#include <locale.h>
+
+#ifdef _ISO_INTERN
+# undef _ISO_INTERN
+#endif
+#define _ISO_INTERN(str1) iso_intern(str1)
+
+#ifdef _OEM_INTERN
+# undef _OEM_INTERN
+#endif
+#ifndef IZ_OEM2ISO_ARRAY
+# define IZ_OEM2ISO_ARRAY
+#endif
+#define _OEM_INTERN(str1) oem_intern(str1)
+
+void iso_intern(char *);
+void oem_intern(char *);
+void init_conversion_charsets(void);
+
#endif /* !__unxcfg_h */
Index: unzip-6.0/unzip.c
===================================================================
--- unzip-6.0.orig/unzip.c 2015-02-11 08:46:43.675324290 -0500
+++ unzip-6.0/unzip.c 2015-02-11 08:46:43.675324290 -0500
@@ -327,11 +327,21 @@
-2 just filenames but allow -h/-t/-z -l long Unix \"ls -l\" format\n\
-v verbose, multi-page format\n";
+#ifndef UNIX
static ZCONST char Far ZipInfoUsageLine3[] = "miscellaneous options:\n\
-h print header line -t print totals for listed files or for all\n\
-z print zipfile comment -T print file times in sortable decimal format\
\n -C be case-insensitive %s\
-x exclude filenames that follow from listing\n";
+#else /* UNIX */
+static ZCONST char Far ZipInfoUsageLine3[] = "miscellaneous options:\n\
+ -h print header line -t print totals for listed files or for all\n\
+ -z print zipfile comment %c-T%c print file times in sortable decimal format\
+\n %c-C%c be case-insensitive %s\
+ -x exclude filenames that follow from listing\n\
+ -O CHARSET specify a character encoding for DOS, Windows and OS/2 archives\n\
+ -I CHARSET specify a character encoding for UNIX and other archives\n";
+#endif /* !UNIX */
#ifdef MORE
static ZCONST char Far ZipInfoUsageLine4[] =
" -M page output through built-in \"more\"\n";
@@ -664,6 +674,17 @@
-U use escapes for all non-ASCII Unicode -UU ignore any Unicode fields\n\
-C match filenames case-insensitively -L make (some) names \
lowercase\n %-42s -V retain VMS version numbers\n%s";
+#elif (defined UNIX)
+static ZCONST char Far UnzipUsageLine4[] = "\
+modifiers:\n\
+ -n never overwrite existing files -q quiet mode (-qq => quieter)\n\
+ -o overwrite files WITHOUT prompting -a auto-convert any text files\n\
+ -j junk paths (do not make directories) -aa treat ALL files as text\n\
+ -U use escapes for all non-ASCII Unicode -UU ignore any Unicode fields\n\
+ -C match filenames case-insensitively -L make (some) names \
+lowercase\n %-42s -V retain VMS version numbers\n%s\
+ -O CHARSET specify a character encoding for DOS, Windows and OS/2 archives\n\
+ -I CHARSET specify a character encoding for UNIX and other archives\n\n";
#else /* !VMS */
static ZCONST char Far UnzipUsageLine4[] = "\
modifiers:\n\
@@ -802,6 +823,10 @@
#endif /* UNICODE_SUPPORT */
+#ifdef UNIX
+ init_conversion_charsets();
+#endif
+
#if (defined(__IBMC__) && defined(__DEBUG_ALLOC__))
extern void DebugMalloc(void);
@@ -1335,6 +1360,11 @@
argc = *pargc;
argv = *pargv;
+#ifdef UNIX
+ extern char OEM_CP[MAX_CP_NAME];
+ extern char ISO_CP[MAX_CP_NAME];
+#endif
+
while (++argv, (--argc > 0 && *argv != NULL && **argv == '-')) {
s = *argv + 1;
while ((c = *s++) != 0) { /* "!= 0": prevent Turbo C warning */
@@ -1516,6 +1546,35 @@
}
break;
#endif /* MACOS */
+#ifdef UNIX
+ case ('I'):
+ if (negative) {
+ Info(slide, 0x401, ((char *)slide,
+ "error: encodings can't be negated"));
+ return(PK_PARAM);
+ } else {
+ if(*s) { /* Handle the -Icharset case */
+ /* Assume that charsets can't start with a dash to spot arguments misuse */
+ if(*s == '-') {
+ Info(slide, 0x401, ((char *)slide,
+ "error: a valid character encoding should follow the -I argument"));
+ return(PK_PARAM);
+ }
+ strncpy(ISO_CP, s, sizeof(ISO_CP));
+ } else { /* -I charset */
+ ++argv;
+ if(!(--argc > 0 && *argv != NULL && **argv != '-')) {
+ Info(slide, 0x401, ((char *)slide,
+ "error: a valid character encoding should follow the -I argument"));
+ return(PK_PARAM);
+ }
+ s = *argv;
+ strncpy(ISO_CP, s, sizeof(ISO_CP));
+ }
+ while(*(++s)); /* No params straight after charset name */
+ }
+ break;
+#endif /* ?UNIX */
case ('j'): /* junk pathnames/directory structure */
if (negative)
uO.jflag = FALSE, negative = 0;
@@ -1591,6 +1650,35 @@
} else
++uO.overwrite_all;
break;
+#ifdef UNIX
+ case ('O'):
+ if (negative) {
+ Info(slide, 0x401, ((char *)slide,
+ "error: encodings can't be negated"));
+ return(PK_PARAM);
+ } else {
+ if(*s) { /* Handle the -Ocharset case */
+ /* Assume that charsets can't start with a dash to spot arguments misuse */
+ if(*s == '-') {
+ Info(slide, 0x401, ((char *)slide,
+ "error: a valid character encoding should follow the -I argument"));
+ return(PK_PARAM);
+ }
+ strncpy(OEM_CP, s, sizeof(OEM_CP));
+ } else { /* -O charset */
+ ++argv;
+ if(!(--argc > 0 && *argv != NULL && **argv != '-')) {
+ Info(slide, 0x401, ((char *)slide,
+ "error: a valid character encoding should follow the -O argument"));
+ return(PK_PARAM);
+ }
+ s = *argv;
+ strncpy(OEM_CP, s, sizeof(OEM_CP));
+ }
+ while(*(++s)); /* No params straight after charset name */
+ }
+ break;
+#endif /* ?UNIX */
case ('p'): /* pipes: extract to stdout, no messages */
if (negative) {
uO.cflag = FALSE;
Index: unzip-6.0/unzpriv.h
===================================================================
--- unzip-6.0.orig/unzpriv.h 2015-02-11 08:46:43.675324290 -0500
+++ unzip-6.0/unzpriv.h 2015-02-11 08:46:43.675324290 -0500
@@ -3008,7 +3008,7 @@
!(((islochdr) || (isuxatt)) && \
((hostver) == 25 || (hostver) == 26 || (hostver) == 40))) || \
(hostnum) == FS_HPFS_ || \
- ((hostnum) == FS_NTFS_ && (hostver) == 50)) { \
+ ((hostnum) == FS_NTFS_ /* && (hostver) == 50 */ )) { \
_OEM_INTERN((string)); \
} else { \
_ISO_INTERN((string)); \
Index: unzip-6.0/zipinfo.c
===================================================================
--- unzip-6.0.orig/zipinfo.c 2015-02-11 08:46:43.675324290 -0500
+++ unzip-6.0/zipinfo.c 2015-02-11 08:46:43.675324290 -0500
@@ -457,6 +457,10 @@
int tflag_slm=TRUE, tflag_2v=FALSE;
int explicit_h=FALSE, explicit_t=FALSE;
+#ifdef UNIX
+ extern char OEM_CP[MAX_CP_NAME];
+ extern char ISO_CP[MAX_CP_NAME];
+#endif
#ifdef MACOS
uO.lflag = LFLAG; /* reset default on each call */
@@ -501,6 +505,35 @@
uO.lflag = 0;
}
break;
+#ifdef UNIX
+ case ('I'):
+ if (negative) {
+ Info(slide, 0x401, ((char *)slide,
+ "error: encodings can't be negated"));
+ return(PK_PARAM);
+ } else {
+ if(*s) { /* Handle the -Icharset case */
+ /* Assume that charsets can't start with a dash to spot arguments misuse */
+ if(*s == '-') {
+ Info(slide, 0x401, ((char *)slide,
+ "error: a valid character encoding should follow the -I argument"));
+ return(PK_PARAM);
+ }
+ strncpy(ISO_CP, s, sizeof(ISO_CP));
+ } else { /* -I charset */
+ ++argv;
+ if(!(--argc > 0 && *argv != NULL && **argv != '-')) {
+ Info(slide, 0x401, ((char *)slide,
+ "error: a valid character encoding should follow the -I argument"));
+ return(PK_PARAM);
+ }
+ s = *argv;
+ strncpy(ISO_CP, s, sizeof(ISO_CP));
+ }
+ while(*(++s)); /* No params straight after charset name */
+ }
+ break;
+#endif /* ?UNIX */
case 'l': /* longer form of "ls -l" type listing */
if (negative)
uO.lflag = -2, negative = 0;
@@ -521,6 +554,35 @@
G.M_flag = TRUE;
break;
#endif
+#ifdef UNIX
+ case ('O'):
+ if (negative) {
+ Info(slide, 0x401, ((char *)slide,
+ "error: encodings can't be negated"));
+ return(PK_PARAM);
+ } else {
+ if(*s) { /* Handle the -Ocharset case */
+ /* Assume that charsets can't start with a dash to spot arguments misuse */
+ if(*s == '-') {
+ Info(slide, 0x401, ((char *)slide,
+ "error: a valid character encoding should follow the -I argument"));
+ return(PK_PARAM);
+ }
+ strncpy(OEM_CP, s, sizeof(OEM_CP));
+ } else { /* -O charset */
+ ++argv;
+ if(!(--argc > 0 && *argv != NULL && **argv != '-')) {
+ Info(slide, 0x401, ((char *)slide,
+ "error: a valid character encoding should follow the -O argument"));
+ return(PK_PARAM);
+ }
+ s = *argv;
+ strncpy(OEM_CP, s, sizeof(OEM_CP));
+ }
+ while(*(++s)); /* No params straight after charset name */
+ }
+ break;
+#endif /* ?UNIX */
case 's': /* default: shorter "ls -l" type listing */
if (negative)
uO.lflag = -2, negative = 0;

12
SOURCES/unzip-6.0-attribs-overflow.patch

@ -0,0 +1,12 @@
diff -up unzip60/zipinfo.c.attribs-overflow unzip60/zipinfo.c
--- unzip60/zipinfo.c.attribs-overflow 2009-11-30 09:55:39.000000000 +0100
+++ unzip60/zipinfo.c 2009-11-30 09:56:42.844263244 +0100
@@ -1881,7 +1881,7 @@ static int zi_short(__G) /* return PK-
#endif
int k, error, error_in_archive=PK_COOL;
unsigned hostnum, hostver, methid, methnum, xattr;
- char *p, workspace[12], attribs[16];
+ char *p, workspace[12], attribs[17];
char methbuf[5];
static ZCONST char dtype[5]="NXFS"; /* normal, maximum, fast, superfast */
static ZCONST char Far os[NUM_HOSTS+1][4] = {

30
SOURCES/unzip-6.0-bzip2-configure.patch

@ -0,0 +1,30 @@
diff -up unzip60/unix/configure.bzip2-configure unzip60/unix/configure
--- unzip60/unix/configure.bzip2-configure 2009-04-16 21:25:12.000000000 +0200
+++ unzip60/unix/configure 2009-11-18 11:22:14.598389194 +0100
@@ -640,7 +640,24 @@ else
D_USE_BZ2="-DUSE_BZIP2"
L_BZ2="${BZLF} -lbz2"
else
- echo "-- bzip2 sources not found - no bzip2 support"
+ echo " Check if OS already has bzip2 library installed"
+ cat > conftest.c << _EOF_
+#include "bzlib.h"
+int main()
+{
+ bz_stream strm;
+ BZ2_bzCompressEnd(&strm);
+ return 0;
+}
+_EOF_
+ $CC $CFLAGS -o conftest conftest.c -lbz2 > /dev/null 2>/dev/null
+ if test $? -eq 0; then
+ echo "-- OS supports bzip2 - linking in bzip2"
+ D_USE_BZ2="-DUSE_BZIP2"
+ L_BZ2="${BZLF} -lbz2"
+ else
+ echo "-- Either bzlib.h or libbz2.a not found - no bzip2"
+ fi
fi
fi

131
SOURCES/unzip-6.0-caseinsensitive.patch

@ -0,0 +1,131 @@
diff --git a/match.c b/match.c
index 6cd656f..4e569f5 100644
--- a/match.c
+++ b/match.c
@@ -190,10 +190,10 @@ char *___tmp_ptr;
#endif
-static int recmatch(p, s, cs)
+static int recmatch(p, s, ci)
ZCONST char *p; /* sh pattern to match */
ZCONST char *s; /* string to match it to */
-int cs; /* flag: force case-sensitive matching */
+int ci; /* flag: force case-insensitive matching */
/* Recursively compare the sh pattern p with the string s and return 1 if
they match, and 0 or 2 if they don't or if there is a syntax error in the
pattern. This routine recurses on itself no deeper than the number of
@@ -214,7 +214,7 @@ int cs; /* flag: force case-sensitive matching */
if (CLEN(p) == 2) {
if (CLEN(s) == 2) {
return (*p == *s && *(p+1) == *(s+1)) ?
- recmatch(p + 2, s + 2, cs) : 0;
+ recmatch(p + 2, s + 2, ci) : 0;
} else {
return 0;
}
@@ -230,9 +230,9 @@ int cs; /* flag: force case-sensitive matching */
/* '?' (or '%' or '#') matches any character (but not an empty string) */
if (c == WILDCHR_SINGLE) {
if (wild_stop_at_dir)
- return (*s && *s != DIRSEP_CHR) ? recmatch(p, s + CLEN(s), cs) : 0;
+ return (*s && *s != DIRSEP_CHR) ? recmatch(p, s + CLEN(s), ci) : 0;
else
- return *s ? recmatch(p, s + CLEN(s), cs) : 0;
+ return *s ? recmatch(p, s + CLEN(s), ci) : 0;
}
/* WILDCHR_MULTI ('*') matches any number of characters, including zero */
@@ -253,14 +253,14 @@ int cs; /* flag: force case-sensitive matching */
# endif /* ?AMIGA */
/* Single WILDCHR_MULTI ('*'): this doesn't match slashes */
for (; *s && *s != DIRSEP_CHR; INCSTR(s))
- if ((c = recmatch(p, s, cs)) != 0)
+ if ((c = recmatch(p, s, ci)) != 0)
return c;
/* end of pattern: matched if at end of string, else continue */
if (*p == 0)
return (*s == 0);
/* continue to match if at DIRSEP_CHR in pattern, else give up */
return (*p == DIRSEP_CHR || (*p == '\\' && p[1] == DIRSEP_CHR))
- ? recmatch(p, s, cs) : 2;
+ ? recmatch(p, s, ci) : 2;
}
/* Two consecutive WILDCHR_MULTI ("**"): this matches DIRSEP_CHR ('/') */
p++; /* move p past the second WILDCHR_MULTI */
@@ -308,17 +308,17 @@ int cs; /* flag: force case-sensitive matching */
*/
if (q != srest)
return 0;
- return ((cs ? strcmp(p, q) : namecmp(p, q)) == 0);
+ return ((!ci ? strcmp(p, q) : namecmp(p, q)) == 0);
}
#else /* !_MBCS */
- return ((cs ? strcmp(p, srest) : namecmp(p, srest)) == 0);
+ return ((!ci ? strcmp(p, srest) : namecmp(p, srest)) == 0);
#endif /* ?_MBCS */
}
else
{
/* pattern contains more wildcards, continue with recursion... */
for (; *s; INCSTR(s))
- if ((c = recmatch(p, s, cs)) != 0)
+ if ((c = recmatch(p, s, ci)) != 0)
return c;
return 2; /* 2 means give up--shmatch will return false */
}
@@ -353,17 +353,17 @@ int cs; /* flag: force case-sensitive matching */
c = *(p-1);
else
{
- uch cc = (cs ? (uch)*s : case_map((uch)*s));
+ uch cc = (!ci ? (uch)*s : to_up((uch)*s));
uch uc = (uch) c;
if (*(p+1) != '-')
for (uc = uc ? uc : (uch)*p; uc <= (uch)*p; uc++)
/* compare range */
- if ((cs ? uc : case_map(uc)) == cc)
- return r ? 0 : recmatch(q + CLEN(q), s + CLEN(s), cs);
+ if ((!ci ? uc : to_up(uc)) == cc)
+ return r ? 0 : recmatch(q + CLEN(q), s + CLEN(s), ci);
c = e = 0; /* clear range, escape flags */
}
}
- return r ? recmatch(q + CLEN(q), s + CLEN(s), cs) : 0;
+ return r ? recmatch(q + CLEN(q), s + CLEN(s), ci) : 0;
/* bracket match failed */
}
#endif /* !VMS */
@@ -382,18 +382,18 @@ int cs; /* flag: force case-sensitive matching */
{
/* Match "...]" with "]". Continue after "]" in both. */
if ((*(p+ 2* CLEN( p)) == ']') && (*s == ']'))
- return recmatch( (p+ 3* CLEN( p)), (s+ CLEN( s)), cs);
+ return recmatch( (p+ 3* CLEN( p)), (s+ CLEN( s)), ci);
/* Else, look for a reduced match in s, until "]" in or end of s. */
for (; *s && (*s != ']'); INCSTR(s))
if (*s == '.')
/* If reduced match, then continue after "..." in p, "." in s. */
- if ((c = recmatch( (p+ CLEN( p)), s, cs)) != 0)
+ if ((c = recmatch( (p+ CLEN( p)), s, ci)) != 0)
return (int)c;
/* Match "...]" with "]". Continue after "]" in both. */
if ((*(p+ 2* CLEN( p)) == ']') && (*s == ']'))
- return recmatch( (p+ 3* CLEN( p)), (s+ CLEN( s)), cs);
+ return recmatch( (p+ 3* CLEN( p)), (s+ CLEN( s)), ci);
/* No reduced match. Quit. */
return 2;
@@ -402,8 +402,8 @@ int cs; /* flag: force case-sensitive matching */
#endif /* def VMS */
/* Just a character--compare it */
- return (cs ? c == *s : case_map((uch)c) == case_map((uch)*s)) ?
- recmatch(p, s + CLEN(s), cs) : 0;
+ return (!ci ? c == *s : to_up((uch)c) == to_up((uch)*s)) ?
+ recmatch(p, s + CLEN(s), ci) : 0;
}

176
SOURCES/unzip-6.0-close.patch

@ -0,0 +1,176 @@
diff -up unzip60/extract.c.close unzip60/extract.c
--- unzip60/extract.c.close 2009-03-14 02:32:52.000000000 +0100
+++ unzip60/extract.c 2009-11-19 08:17:23.481263496 +0100
@@ -1924,24 +1924,21 @@ static int extract_or_test_member(__G)
#ifdef VMS /* VMS: required even for stdout! (final flush) */
if (!uO.tflag) /* don't close NULL file */
- close_outfile(__G);
+ error = close_outfile(__G);
#else
#ifdef DLL
if (!uO.tflag && (!uO.cflag || G.redirect_data)) {
if (G.redirect_data)
FINISH_REDIRECT();
else
- close_outfile(__G);
+ error = close_outfile(__G);
}
#else
if (!uO.tflag && !uO.cflag) /* don't close NULL file or stdout */
- close_outfile(__G);
+ error = close_outfile(__G);
#endif
#endif /* VMS */
- /* GRR: CONVERT close_outfile() TO NON-VOID: CHECK FOR ERRORS! */
-
-
if (G.disk_full) { /* set by flush() */
if (G.disk_full > 1) {
#if (defined(DELETE_IF_FULL) && defined(HAVE_UNLINK))
diff -up unzip60/unix/unix.c.close unzip60/unix/unix.c
--- unzip60/unix/unix.c.close 2009-01-24 00:31:26.000000000 +0100
+++ unzip60/unix/unix.c 2009-11-19 08:33:25.568389171 +0100
@@ -1096,10 +1096,41 @@ static int get_extattribs(__G__ pzt, z_u
#ifndef MTS
/****************************/
+/* Function CloseError() */
+/***************************/
+
+int CloseError(__G)
+ __GDEF
+{
+ int errval = PK_OK;
+
+ if (fclose(G.outfile) < 0) {
+ switch (errno) {
+ case ENOSPC:
+ /* Do we need this on fileio.c? */
+ Info(slide, 0x4a1, ((char *)slide, "%s: write error (disk full?). Continue? (y/n/^C) ",
+ FnFilter1(G.filename)));
+ fgets(G.answerbuf, 9, stdin);
+ if (*G.answerbuf == 'y') /* stop writing to this file */
+ G.disk_full = 1; /* pass to next */
+ else
+ G.disk_full = 2; /* no: exit program */
+
+ errval = PK_DISK;
+ break;
+
+ default:
+ errval = PK_WARN;
+ }
+ }
+ return errval;
+} /* End of CloseError() */
+
+/****************************/
/* Function close_outfile() */
/****************************/
-void close_outfile(__G) /* GRR: change to return PK-style warning level */
+int close_outfile(__G)
__GDEF
{
union {
@@ -1108,6 +1139,7 @@ void close_outfile(__G) /* GRR: chang
} zt;
ulg z_uidgid[2];
int have_uidgid_flg;
+ int errval = PK_OK;
have_uidgid_flg = get_extattribs(__G__ &(zt.t3), z_uidgid);
@@ -1141,16 +1173,16 @@ void close_outfile(__G) /* GRR: chang
Info(slide, 0x201, ((char *)slide,
"warning: symbolic link (%s) failed: mem alloc overflow\n",
FnFilter1(G.filename)));
- fclose(G.outfile);
- return;
+ errval = CloseError(G.outfile, G.filename);
+ return errval ? errval : PK_WARN;
}
if ((slnk_entry = (slinkentry *)malloc(slnk_entrysize)) == NULL) {
Info(slide, 0x201, ((char *)slide,
"warning: symbolic link (%s) failed: no mem\n",
FnFilter1(G.filename)));
- fclose(G.outfile);
- return;
+ errval = CloseError(G.outfile, G.filename);
+ return errval ? errval : PK_WARN;
}
slnk_entry->next = NULL;
slnk_entry->targetlen = ucsize;
@@ -1174,10 +1206,10 @@ void close_outfile(__G) /* GRR: chang
"warning: symbolic link (%s) failed\n",
FnFilter1(G.filename)));
free(slnk_entry);
- fclose(G.outfile);
- return;
+ errval = CloseError(G.outfile, G.filename);
+ return errval ? errval : PK_WARN;
}
- fclose(G.outfile); /* close "link" file for good... */
+ errval = CloseError(G.outfile, G.filename); /* close "link" file for good... */
slnk_entry->target[ucsize] = '\0';
if (QCOND2)
Info(slide, 0, ((char *)slide, "-> %s ",
@@ -1188,7 +1220,7 @@ void close_outfile(__G) /* GRR: chang
else
G.slink_head = slnk_entry;
G.slink_last = slnk_entry;
- return;
+ return errval;
}
#endif /* SYMLINKS */
@@ -1201,7 +1233,7 @@ void close_outfile(__G) /* GRR: chang
#endif
#if (defined(NO_FCHOWN))
- fclose(G.outfile);
+ errval = CloseError(G.outfile, G.filename);
#endif
/* if -X option was specified and we have UID/GID info, restore it */
@@ -1227,7 +1259,7 @@ void close_outfile(__G) /* GRR: chang
}
#if (!defined(NO_FCHOWN) && defined(NO_FCHMOD))
- fclose(G.outfile);
+ errval = CloseError(G.outfile, G.filename);
#endif
#if (!defined(NO_FCHOWN) && !defined(NO_FCHMOD))
@@ -1239,7 +1271,7 @@ void close_outfile(__G) /* GRR: chang
if (fchmod(fileno(G.outfile), filtattr(__G__ G.pInfo->file_attr)))
perror("fchmod (file attributes) error");
- fclose(G.outfile);
+ errval = CloseError(G.outfile, G.filename);
#endif /* !NO_FCHOWN && !NO_FCHMOD */
/* skip restoring time stamps on user's request */
@@ -1267,6 +1299,7 @@ void close_outfile(__G) /* GRR: chang
#endif
#endif /* NO_FCHOWN || NO_FCHMOD */
+ return errval;
} /* end function close_outfile() */
#endif /* !MTS */
diff -up unzip60/unzpriv.h.close unzip60/unzpriv.h
--- unzip60/unzpriv.h.close 2009-04-20 01:59:26.000000000 +0200
+++ unzip60/unzpriv.h 2009-11-19 08:19:08.610388618 +0100
@@ -2604,7 +2604,7 @@ char *GetLoadPath OF((__GPRO));
int SetFileSize OF((FILE *file, zusz_t filesize)); /* local */
#endif
#ifndef MTS /* macro in MTS */
- void close_outfile OF((__GPRO)); /* local */
+ int close_outfile OF((__GPRO)); /* local */
#endif
#ifdef SET_SYMLINK_ATTRIBS
int set_symlnk_attribs OF((__GPRO__ slinkentry *slnk_entry)); /* local */

12
SOURCES/unzip-6.0-configure.patch

@ -0,0 +1,12 @@
diff -up unzip60/unix/configure.nostrip unzip60/unix/configure
--- unzip60/unix/configure.nostrip 2009-11-30 10:18:09.000000000 +0100
+++ unzip60/unix/configure 2009-11-30 10:21:08.354264213 +0100
@@ -17,7 +17,7 @@ CFLAGSR=${CFLAGS}
IZ_BZIP2=${3}
CFLAGS="${CFLAGS} -I. -DUNIX"
LFLAGS1=""
-LFLAGS2="-s"
+LFLAGS2="${LFLAGS2}"
LN="ln -s"
CFLAGS_OPT=''

79
SOURCES/unzip-6.0-cve-2014-8139.patch

@ -0,0 +1,79 @@
diff --git a/extract.c b/extract.c
index 9ef80b3..c741b5f 100644
--- a/extract.c
+++ b/extract.c
@@ -1,5 +1,5 @@
/*
- Copyright (c) 1990-2009 Info-ZIP. All rights reserved.
+ Copyright (c) 1990-2014 Info-ZIP. All rights reserved.
See the accompanying file LICENSE, version 2009-Jan-02 or later
(the contents of which are also included in unzip.h) for terms of use.
@@ -298,6 +298,8 @@ char ZCONST Far TruncNTSD[] =
#ifndef SFX
static ZCONST char Far InconsistEFlength[] = "bad extra-field entry:\n \
EF block length (%u bytes) exceeds remaining EF data (%u bytes)\n";
+ static ZCONST char Far TooSmallEBlength[] = "bad extra-field entry:\n \
+ EF block length (%u bytes) invalid (< %d)\n";
static ZCONST char Far InvalidComprDataEAs[] =
" invalid compressed data for EAs\n";
# if (defined(WIN32) && defined(NTSD_EAS))
@@ -2020,7 +2022,8 @@ static int TestExtraField(__G__ ef, ef_len)
ebID = makeword(ef);
ebLen = (unsigned)makeword(ef+EB_LEN);
- if (ebLen > (ef_len - EB_HEADSIZE)) {
+ if (ebLen > (ef_len - EB_HEADSIZE))
+ {
/* Discovered some extra field inconsistency! */
if (uO.qflag)
Info(slide, 1, ((char *)slide, "%-22s ",
@@ -2155,11 +2158,29 @@ static int TestExtraField(__G__ ef, ef_len)
}
break;
case EF_PKVMS:
- if (makelong(ef+EB_HEADSIZE) !=
- crc32(CRCVAL_INITIAL, ef+(EB_HEADSIZE+4),
- (extent)(ebLen-4)))
- Info(slide, 1, ((char *)slide,
- LoadFarString(BadCRC_EAs)));
+ /* 2015-01-30 SMS. Added sufficient-bytes test/message
+ * here. (Removed defective ebLen test above.)
+ *
+ * If sufficient bytes (EB_PKVMS_MINLEN) are available,
+ * then compare the stored CRC value with the calculated
+ * CRC for the remainder of the data (and complain about
+ * a mismatch).
+ */
+ if (ebLen < EB_PKVMS_MINLEN)
+ {
+ /* Insufficient bytes available. */
+ Info( slide, 1,
+ ((char *)slide, LoadFarString( TooSmallEBlength),
+ ebLen, EB_PKVMS_MINLEN));
+ }
+ else if (makelong(ef+ EB_HEADSIZE) !=
+ crc32(CRCVAL_INITIAL,
+ (ef+ EB_HEADSIZE+ EB_PKVMS_MINLEN),
+ (extent)(ebLen- EB_PKVMS_MINLEN)))
+ {
+ Info(slide, 1, ((char *)slide,
+ LoadFarString(BadCRC_EAs)));
+ }
break;
case EF_PKW32:
case EF_PKUNIX:
diff --git a/unzpriv.h b/unzpriv.h
index 005cee0..5c83a6e 100644
--- a/unzpriv.h
+++ b/unzpriv.h
@@ -1806,6 +1806,8 @@
#define EB_NTSD_VERSION 4 /* offset of NTSD version byte */
#define EB_NTSD_MAX_VER (0) /* maximum version # we know how to handle */
+#define EB_PKVMS_MINLEN 4 /* minimum data length of PKVMS extra block */
+
#define EB_ASI_CRC32 0 /* offset of ASI Unix field's crc32 checksum */
#define EB_ASI_MODE 4 /* offset of ASI Unix permission mode field */

25
SOURCES/unzip-6.0-cve-2014-8140.patch

@ -0,0 +1,25 @@
diff --git a/extract.c b/extract.c
index c741b5f..e4a4c7b 100644
--- a/extract.c
+++ b/extract.c
@@ -2240,10 +2240,17 @@ static int test_compr_eb(__G__ eb, eb_size, compr_offset, test_uc_ebdata)
if (compr_offset < 4) /* field is not compressed: */
return PK_OK; /* do nothing and signal OK */
+ /* Return no/bad-data error status if any problem is found:
+ * 1. eb_size is too small to hold the uncompressed size
+ * (eb_ucsize). (Else extract eb_ucsize.)
+ * 2. eb_ucsize is zero (invalid). 2014-12-04 SMS.
+ * 3. eb_ucsize is positive, but eb_size is too small to hold
+ * the compressed data header.
+ */
if ((eb_size < (EB_UCSIZE_P + 4)) ||
- ((eb_ucsize = makelong(eb+(EB_HEADSIZE+EB_UCSIZE_P))) > 0L &&
- eb_size <= (compr_offset + EB_CMPRHEADLEN)))
- return IZ_EF_TRUNC; /* no compressed data! */
+ ((eb_ucsize = makelong( eb+ (EB_HEADSIZE+ EB_UCSIZE_P))) == 0L) ||
+ ((eb_ucsize > 0L) && (eb_size <= (compr_offset + EB_CMPRHEADLEN))))
+ return IZ_EF_TRUNC; /* no/bad compressed data! */
method = makeword(eb + (EB_HEADSIZE + compr_offset));
if ((method == STORED) && (eb_size != compr_offset + EB_CMPRHEADLEN + eb_ucsize))

138
SOURCES/unzip-6.0-cve-2014-8141.patch

@ -0,0 +1,138 @@
diff --git a/fileio.c b/fileio.c
index 03fc4be..2a61a30 100644
--- a/fileio.c
+++ b/fileio.c
@@ -176,6 +176,8 @@ static ZCONST char Far FilenameTooLongTrunc[] =
#endif
static ZCONST char Far ExtraFieldTooLong[] =
"warning: extra field too long (%d). Ignoring...\n";
+static ZCONST char Far ExtraFieldCorrupt[] =
+ "warning: extra field (type: 0x%04x) corrupt. Continuing...\n";
#ifdef WINDLL
static ZCONST char Far DiskFullQuery[] =
@@ -2300,7 +2302,13 @@ int do_string(__G__ length, option) /* return PK-type error code */
length = length2;
}
/* Looks like here is where extra fields are read */
- getZip64Data(__G__ G.extra_field, length);
+ if (getZip64Data(__G__ G.extra_field, length) != PK_COOL)
+ {
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString( ExtraFieldCorrupt), EF_PKSZ64));
+ error = PK_WARN;
+ }
+
#ifdef UNICODE_SUPPORT
G.unipath_filename = NULL;
if (G.UzO.U_flag < 2) {
diff --git a/process.c b/process.c
index be6e006..0d57ab4 100644
--- a/process.c
+++ b/process.c
@@ -1,5 +1,5 @@
/*
- Copyright (c) 1990-2009 Info-ZIP. All rights reserved.
+ Copyright (c) 1990-2014 Info-ZIP. All rights reserved.
See the accompanying file LICENSE, version 2009-Jan-02 or later
(the contents of which are also included in unzip.h) for terms of use.
@@ -1894,48 +1894,83 @@ int getZip64Data(__G__ ef_buf, ef_len)
and a 4-byte version of disk start number.
Sets both local header and central header fields. Not terribly clever,
but it means that this procedure is only called in one place.
+
+ 2014-12-05 SMS.
+ Added checks to ensure that enough data are available before calling
+ makeint64() or makelong(). Replaced various sizeof() values with
+ simple ("4" or "8") constants. (The Zip64 structures do not depend
+ on our variable sizes.) Error handling is crude, but we should now
+ stay within the buffer.
---------------------------------------------------------------------------*/
+#define Z64FLGS 0xffff
+#define Z64FLGL 0xffffffff
+
if (ef_len == 0 || ef_buf == NULL)
return PK_COOL;
Trace((stderr,"\ngetZip64Data: scanning extra field of length %u\n",
ef_len));
- while (ef_len >= EB_HEADSIZE) {
+ while (ef_len >= EB_HEADSIZE)
+ {
eb_id = makeword(EB_ID + ef_buf);
eb_len = makeword(EB_LEN + ef_buf);
- if (eb_len > (ef_len - EB_HEADSIZE)) {
- /* discovered some extra field inconsistency! */
+ if (eb_len > (ef_len - EB_HEADSIZE))
+ {
+ /* Extra block length exceeds remaining extra field length. */
Trace((stderr,
"getZip64Data: block length %u > rest ef_size %u\n", eb_len,
ef_len - EB_HEADSIZE));
break;
}
- if (eb_id == EF_PKSZ64) {
+ if (eb_id == EF_PKSZ64)
+ {
int offset = EB_HEADSIZE;
- if (G.crec.ucsize == 0xffffffff || G.lrec.ucsize == 0xffffffff){
- G.lrec.ucsize = G.crec.ucsize = makeint64(offset + ef_buf);
- offset += sizeof(G.crec.ucsize);
+ if ((G.crec.ucsize == Z64FLGL) || (G.lrec.ucsize == Z64FLGL))
+ {
+ if (offset+ 8 > ef_len)
+ return PK_ERR;
+
+ G.crec.ucsize = G.lrec.ucsize = makeint64(offset + ef_buf);
+ offset += 8;
}
- if (G.crec.csize == 0xffffffff || G.lrec.csize == 0xffffffff){
- G.csize = G.lrec.csize = G.crec.csize = makeint64(offset + ef_buf);
- offset += sizeof(G.crec.csize);
+
+ if ((G.crec.csize == Z64FLGL) || (G.lrec.csize == Z64FLGL))
+ {
+ if (offset+ 8 > ef_len)
+ return PK_ERR;
+
+ G.csize = G.crec.csize = G.lrec.csize = makeint64(offset + ef_buf);
+ offset += 8;
}
- if (G.crec.relative_offset_local_header == 0xffffffff){
+
+ if (G.crec.relative_offset_local_header == Z64FLGL)
+ {
+ if (offset+ 8 > ef_len)
+ return PK_ERR;
+
G.crec.relative_offset_local_header = makeint64(offset + ef_buf);
- offset += sizeof(G.crec.relative_offset_local_header);
+ offset += 8;
}
- if (G.crec.disk_number_start == 0xffff){
+
+ if (G.crec.disk_number_start == Z64FLGS)
+ {
+ if (offset+ 4 > ef_len)
+ return PK_ERR;
+
G.crec.disk_number_start = (zuvl_t)makelong(offset + ef_buf);
- offset += sizeof(G.crec.disk_number_start);
+ offset += 4;
}
+#if 0
+ break; /* Expect only one EF_PKSZ64 block. */
+#endif /* 0 */
}
- /* Skip this extra field block */
+ /* Skip this extra field block. */
ef_buf += (eb_len + EB_HEADSIZE);
ef_len -= (eb_len + EB_HEADSIZE);
}

34
SOURCES/unzip-6.0-cve-2018-1000035-heap-based-overflow.patch

@ -0,0 +1,34 @@
--- a/fileio.c 2014-12-05 05:06:05 -0600
+++ b/fileio.c 2017-11-14 01:06:28 -0600
@@ -1,5 +1,5 @@
/*
- Copyright (c) 1990-2009 Info-ZIP. All rights reserved.
+ Copyright (c) 1990-2017 Info-ZIP. All rights reserved.
See the accompanying file LICENSE, version 2009-Jan-02 or later
(the contents of which are also included in unzip.h) for terms of use.
@@ -1582,6 +1582,8 @@
int r = IZ_PW_ENTERED;
char *m;
char *prompt;
+ char *ep;
+ char *zp;
#ifndef REENTRANT
/* tell picky compilers to shut up about "unused variable" warnings */
@@ -1590,9 +1592,12 @@
if (*rcnt == 0) { /* First call for current entry */
*rcnt = 2;
- if ((prompt = (char *)malloc(2*FILNAMSIZ + 15)) != (char *)NULL) {
- sprintf(prompt, LoadFarString(PasswPrompt),
- FnFilter1(zfn), FnFilter2(efn));
+ zp = FnFilter1( zfn);
+ ep = FnFilter2( efn);
+ prompt = (char *)malloc( /* Slightly too long (2* "%s"). */
+ sizeof( PasswPrompt)+ strlen( zp)+ strlen( ep));
+ if (prompt != (char *)NULL) {
+ sprintf(prompt, LoadFarString(PasswPrompt), zp, ep);
m = prompt;
} else
m = (char *)LoadFarString(PasswPrompt2);

35
SOURCES/unzip-6.0-cve-2018-18384.patch

@ -0,0 +1,35 @@
--- unzip60/list.c
+++ unzip60/list.c
@@ -97,7 +97,7 @@ int list_files(__G) /* return PK-type
{
int do_this_file=FALSE, cfactor, error, error_in_archive=PK_COOL;
#ifndef WINDLL
- char sgn, cfactorstr[13];
+ char sgn, cfactorstr[1+10+1+1]; /* <sgn><int>%NUL */
int longhdr=(uO.vflag>1);
#endif
int date_format;
@@ -389,9 +389,9 @@ int list_files(__G) /* return PK-type
}
#else /* !WINDLL */
if (cfactor == 100)
- sprintf(cfactorstr, LoadFarString(CompFactor100));
+ snprintf(cfactorstr, sizeof(cfactorstr), LoadFarString(CompFactor100));
else
- sprintf(cfactorstr, LoadFarString(CompFactorStr), sgn, cfactor);
+ snprintf(cfactorstr, sizeof(cfactorstr), LoadFarString(CompFactorStr), sgn, cfactor);
if (longhdr)
Info(slide, 0, ((char *)slide, LoadFarString(LongHdrStats),
FmZofft(G.crec.ucsize, "8", "u"), methbuf,
@@ -471,9 +471,9 @@ int list_files(__G) /* return PK-type
#else /* !WINDLL */
if (cfactor == 100)
- sprintf(cfactorstr, LoadFarString(CompFactor100));
+ snprintf(cfactorstr, sizeof(cfactorstr), LoadFarString(CompFactor100));
else
- sprintf(cfactorstr, LoadFarString(CompFactorStr), sgn, cfactor);
+ snprintf(cfactorstr, sizeof(cfactorstr), LoadFarString(CompFactorStr), sgn, cfactor);
if (longhdr) {
Info(slide, 0, ((char *)slide, LoadFarString(LongFileTrailer),
FmZofft(tot_ucsize, "8", "u"), FmZofft(tot_csize, "8", "u"),

10
SOURCES/unzip-6.0-exec-shield.patch

@ -0,0 +1,10 @@
diff -up unzip60/crc_i386.S.exec-shield unzip60/crc_i386.S
--- unzip60/crc_i386.S.exec-shield 2007-01-07 06:02:58.000000000 +0100
+++ unzip60/crc_i386.S 2009-11-18 11:16:39.630389312 +0100
@@ -302,3 +302,6 @@ _crc32: /* ulg c
#endif /* i386 || _i386 || _I386 || __i386 */
#endif /* !USE_ZLIB && !CRC_TABLE_ONLY */
+
+.section .note.GNU-stack, "", @progbits
+.previous

477
SOURCES/unzip-6.0-fix-recmatch.patch

@ -0,0 +1,477 @@
diff -up unzip60/match.c.recmatch unzip60/match.c
--- unzip60/match.c.recmatch 2005-08-14 13:00:36.000000000 -0400
+++ unzip60/match.c 2013-05-28 10:29:57.949077543 -0400
@@ -27,16 +27,14 @@
---------------------------------------------------------------------------
- Copyright on recmatch() from Zip's util.c (although recmatch() was almost
- certainly written by Mark Adler...ask me how I can tell :-) ):
+ Copyright on recmatch() from Zip's util.c
+ Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
- Copyright (C) 1990-1992 Mark Adler, Richard B. Wales, Jean-loup Gailly,
- Kai Uwe Rommel and Igor Mandrichenko.
+ See the accompanying file LICENSE, version 2004-May-22 or later
+ for terms of use.
+ If, for some reason, both of these files are missing, the Info-ZIP license
+ also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
- Permission is granted to any individual or institution to use, copy,
- or redistribute this software so long as all of the original files are
- included unmodified, that it is not sold for profit, and that this copy-
- right notice is retained.
---------------------------------------------------------------------------
@@ -53,7 +51,7 @@
A set is composed of characters or ranges; a range looks like ``character
hyphen character'' (as in 0-9 or A-Z). [0-9a-zA-Z_] is the minimal set of
- characters allowed in the [..] pattern construct. Other characters are
+ characters ALlowed in the [..] pattern construct. Other characters are
allowed (i.e., 8-bit characters) if your system will support them.
To suppress the special syntactic significance of any of ``[]*?!^-\'', in-
@@ -101,8 +99,32 @@
# define WILDCHAR '?'
# define BEG_RANGE '['
# define END_RANGE ']'
+# define WILDCHR_SINGLE '?'
+# define DIRSEP_CHR '/'
+# define WILDCHR_MULTI '*'
#endif
+#ifdef WILD_STOP_AT_DIR
+ int wild_stop_at_dir = 1; /* default wildcards do not include / in matches */
+#else
+ int wild_stop_at_dir = 0; /* default wildcards do include / in matches */
+#endif
+
+
+
+/*
+ * case mapping functions. case_map is used to ignore case in comparisons,
+ * to_up is used to force upper case even on Unix (for dosify option).
+ */
+#ifdef USE_CASE_MAP
+# define case_map(c) upper[(c) & 0xff]
+# define to_up(c) upper[(c) & 0xff]
+#else
+# define case_map(c) (c)
+# define to_up(c) ((c) >= 'a' && (c) <= 'z' ? (c)-'a'+'A' : (c))
+#endif /* USE_CASE_MAP */
+
+
#if 0 /* GRR: add this to unzip.h someday... */
#if !(defined(MSDOS) && defined(DOSWILD))
#ifdef WILD_STOP_AT_DIR
@@ -114,8 +136,8 @@ int recmatch OF((ZCONST uch *pattern, ZC
int ignore_case __WDLPRO));
#endif
#endif /* 0 */
-static int recmatch OF((ZCONST uch *pattern, ZCONST uch *string,
- int ignore_case __WDLPRO));
+static int recmatch OF((ZCONST char *, ZCONST char *,
+ int));
static char *isshexp OF((ZCONST char *p));
static int namecmp OF((ZCONST char *s1, ZCONST char *s2));
@@ -154,192 +176,240 @@ int match(string, pattern, ignore_case _
}
dospattern[j-1] = '\0'; /* nuke the end "." */
}
- j = recmatch((uch *)dospattern, (uch *)string, ignore_case __WDL);
+ j = recmatch(dospattern, string, ignore_case);
free(dospattern);
return j == 1;
} else
#endif /* MSDOS && DOSWILD */
- return recmatch((uch *)pattern, (uch *)string, ignore_case __WDL) == 1;
+ return recmatch(pattern, string, ignore_case) == 1;
}
+#ifdef _MBCS
+
+char *___tmp_ptr;
+#endif
-static int recmatch(p, s, ic __WDL)
- ZCONST uch *p; /* sh pattern to match */
- ZCONST uch *s; /* string to which to match it */
- int ic; /* true for case insensitivity */
- __WDLDEF /* directory sepchar for WildStopAtDir mode, or 0 */
+static int recmatch(p, s, cs)
+ZCONST char *p; /* sh pattern to match */
+ZCONST char *s; /* string to match it to */
+int cs; /* flag: force case-sensitive matching */
/* Recursively compare the sh pattern p with the string s and return 1 if
- * they match, and 0 or 2 if they don't or if there is a syntax error in the
- * pattern. This routine recurses on itself no more deeply than the number
- * of characters in the pattern. */
+ they match, and 0 or 2 if they don't or if there is a syntax error in the
+ pattern. This routine recurses on itself no deeper than the number of
+ characters in the pattern. */
{
- unsigned int c; /* pattern char or start of range in [-] loop */
+ int c; /* pattern char or start of range in [-] loop */
+ /* Get first character, the pattern for new recmatch calls follows */
+ /* borrowed from Zip's global.c */
+ int no_wild = 0;
+ int allow_regex=1;
+ /* This fix provided by akt@m5.dion.ne.jp for Japanese.
+ See 21 July 2006 mail.
+ It only applies when p is pointing to a doublebyte character and
+ things like / and wildcards are not doublebyte. This probably
+ should not be needed. */
- /* Get first character, the pattern for new recmatch calls follows */
- c = *p; INCSTR(p);
+#ifdef _MBCS
+ if (CLEN(p) == 2) {
+ if (CLEN(s) == 2) {
+ return (*p == *s && *(p+1) == *(s+1)) ?
+ recmatch(p + 2, s + 2, cs) : 0;
+ } else {
+ return 0;
+ }
+ }
+#endif /* ?_MBCS */
- /* If that was the end of the pattern, match if string empty too */
- if (c == 0)
- return *s == 0;
+ c = *POSTINCSTR(p);
- /* '?' (or '%') matches any character (but not an empty string). */
- if (c == WILDCHAR)
-#ifdef WILD_STOP_AT_DIR
- /* If uO.W_flag is non-zero, it won't match '/' */
- return (*s && (!sepc || *s != (uch)sepc))
- ? recmatch(p, s + CLEN(s), ic, sepc) : 0;
-#else
- return *s ? recmatch(p, s + CLEN(s), ic) : 0;
-#endif
+ /* If that was the end of the pattern, match if string empty too */
+ if (c == 0)
+ return *s == 0;
+
+ /* '?' (or '%' or '#') matches any character (but not an empty string) */
+ if (c == WILDCHR_SINGLE) {
+ if (wild_stop_at_dir)
+ return (*s && *s != DIRSEP_CHR) ? recmatch(p, s + CLEN(s), cs) : 0;
+ else
+ return *s ? recmatch(p, s + CLEN(s), cs) : 0;
+ }
- /* '*' matches any number of characters, including zero */
+ /* WILDCHR_MULTI ('*') matches any number of characters, including zero */
#ifdef AMIGA
- if (c == '#' && *p == '?') /* "#?" is Amiga-ese for "*" */
- c = '*', p++;
+ if (!no_wild && c == '#' && *p == '?') /* "#?" is Amiga-ese for "*" */
+ c = WILDCHR_MULTI, p++;
#endif /* AMIGA */
- if (c == '*') {
-#ifdef WILD_STOP_AT_DIR
- if (sepc) {
- /* check for single "*" or double "**" */
-# ifdef AMIGA
- if ((c = p[0]) == '#' && p[1] == '?') /* "#?" is Amiga-ese for "*" */
- c = '*', p++;
- if (c != '*') {
-# else /* !AMIGA */
- if (*p != '*') {
-# endif /* ?AMIGA */
- /* single "*": this doesn't match the dirsep character */
- for (; *s && *s != (uch)sepc; INCSTR(s))
- if ((c = recmatch(p, s, ic, sepc)) != 0)
- return (int)c;
- /* end of pattern: matched if at end of string, else continue */
- if (*p == '\0')
- return (*s == 0);
- /* continue to match if at sepc in pattern, else give up */
- return (*p == (uch)sepc || (*p == '\\' && p[1] == (uch)sepc))
- ? recmatch(p, s, ic, sepc) : 2;
- }
- /* "**": this matches slashes */
- ++p; /* move p behind the second '*' */
- /* and continue with the non-W_flag code variant */
- }
-#endif /* WILD_STOP_AT_DIR */
+ if (!no_wild && c == WILDCHR_MULTI)
+ {
+ if (wild_stop_at_dir) {
+ /* Check for an immediately following WILDCHR_MULTI */
+# ifdef AMIGA
+ if ((c = p[0]) == '#' && p[1] == '?') /* "#?" is Amiga-ese for "*" */
+ c = WILDCHR_MULTI, p++;
+ if (c != WILDCHR_MULTI) {
+# else /* !AMIGA */
+ if (*p != WILDCHR_MULTI) {
+# endif /* ?AMIGA */
+ /* Single WILDCHR_MULTI ('*'): this doesn't match slashes */
+ for (; *s && *s != DIRSEP_CHR; INCSTR(s))
+ if ((c = recmatch(p, s, cs)) != 0)
+ return c;
+ /* end of pattern: matched if at end of string, else continue */
if (*p == 0)
- return 1;
- if (isshexp((ZCONST char *)p) == NULL) {
- /* Optimization for rest of pattern being a literal string:
- * If there are no other shell expression chars in the rest
- * of the pattern behind the multi-char wildcard, then just
- * compare the literal string tail.
- */
- ZCONST uch *srest;
-
- srest = s + (strlen((ZCONST char *)s) - strlen((ZCONST char *)p));
- if (srest - s < 0)
- /* remaining literal string from pattern is longer than rest
- * of test string, there can't be a match
- */
- return 0;
- else
- /* compare the remaining literal pattern string with the last
- * bytes of the test string to check for a match
- */
+ return (*s == 0);
+ /* continue to match if at DIRSEP_CHR in pattern, else give up */
+ return (*p == DIRSEP_CHR || (*p == '\\' && p[1] == DIRSEP_CHR))
+ ? recmatch(p, s, cs) : 2;
+ }
+ /* Two consecutive WILDCHR_MULTI ("**"): this matches DIRSEP_CHR ('/') */
+ p++; /* move p past the second WILDCHR_MULTI */
+ /* continue with the normal non-WILD_STOP_AT_DIR code */
+ } /* wild_stop_at_dir */
+
+ /* Not wild_stop_at_dir */
+ if (*p == 0)
+ return 1;
+ if (!isshexp((char *)p))
+ {
+ /* optimization for rest of pattern being a literal string */
+
+ /* optimization to handle patterns like *.txt */
+ /* if the first char in the pattern is '*' and there */
+ /* are no other shell expression chars, i.e. a literal string */
+ /* then just compare the literal string at the end */
+
+ ZCONST char *srest;
+
+ srest = s + (strlen(s) - strlen(p));
+ if (srest - s < 0)
+ /* remaining literal string from pattern is longer than rest of
+ test string, there can't be a match
+ */
+ return 0;
+ else
+ /* compare the remaining literal pattern string with the last bytes
+ of the test string to check for a match */
#ifdef _MBCS
- {
- ZCONST uch *q = s;
+ {
+ ZCONST char *q = s;
- /* MBCS-aware code must not scan backwards into a string from
- * the end.
- * So, we have to move forward by character from our well-known
- * character position s in the test string until we have
- * advanced to the srest position.
- */
- while (q < srest)
- INCSTR(q);
- /* In case the byte *srest is a trailing byte of a multibyte
- * character in the test string s, we have actually advanced
- * past the position (srest).
- * For this case, the match has failed!
- */
- if (q != srest)
- return 0;
- return ((ic
- ? namecmp((ZCONST char *)p, (ZCONST char *)q)
- : strcmp((ZCONST char *)p, (ZCONST char *)q)
- ) == 0);
- }
+ /* MBCS-aware code must not scan backwards into a string from
+ * the end.
+ * So, we have to move forward by character from our well-known
+ * character position s in the test string until we have advanced
+ * to the srest position.
+ */
+ while (q < srest)
+ INCSTR(q);
+ /* In case the byte *srest is a trailing byte of a multibyte
+ * character, we have actually advanced past the position (srest).
+ * For this case, the match has failed!
+ */
+ if (q != srest)
+ return 0;
+ return ((cs ? strcmp(p, q) : namecmp(p, q)) == 0);
+ }
#else /* !_MBCS */
- return ((ic
- ? namecmp((ZCONST char *)p, (ZCONST char *)srest)
- : strcmp((ZCONST char *)p, (ZCONST char *)srest)
- ) == 0);
+ return ((cs ? strcmp(p, srest) : namecmp(p, srest)) == 0);
#endif /* ?_MBCS */
- } else {
- /* pattern contains more wildcards, continue with recursion... */
- for (; *s; INCSTR(s))
- if ((c = recmatch(p, s, ic __WDL)) != 0)
- return (int)c;
- return 2; /* 2 means give up--match will return false */
- }
}
-
- /* Parse and process the list of characters and ranges in brackets */
- if (c == BEG_RANGE) {
- int e; /* flag true if next char to be taken literally */
- ZCONST uch *q; /* pointer to end of [-] group */
- int r; /* flag true to match anything but the range */
-
- if (*s == 0) /* need a character to match */
- return 0;
- p += (r = (*p == '!' || *p == '^')); /* see if reverse */
- for (q = p, e = 0; *q; INCSTR(q)) /* find closing bracket */
- if (e)
- e = 0;
- else
- if (*q == '\\') /* GRR: change to ^ for MS-DOS, OS/2? */
- e = 1;
- else if (*q == END_RANGE)
- break;
- if (*q != END_RANGE) /* nothing matches if bad syntax */
- return 0;
- for (c = 0, e = (*p == '-'); p < q; INCSTR(p)) {
- /* go through the list */
- if (!e && *p == '\\') /* set escape flag if \ */
- e = 1;
- else if (!e && *p == '-') /* set start of range if - */
- c = *(p-1);
- else {
- unsigned int cc = Case(*s);
-
- if (*(p+1) != '-')
- for (c = c ? c : *p; c <= *p; c++) /* compare range */
- if ((unsigned)Case(c) == cc) /* typecast for MSC bug */
- return r ? 0 : recmatch(q + 1, s + 1, ic __WDL);
- c = e = 0; /* clear range, escape flags */
- }
- }
- return r ? recmatch(q + CLEN(q), s + CLEN(s), ic __WDL) : 0;
- /* bracket match failed */
+ else
+ {
+ /* pattern contains more wildcards, continue with recursion... */
+ for (; *s; INCSTR(s))
+ if ((c = recmatch(p, s, cs)) != 0)
+ return c;
+ return 2; /* 2 means give up--shmatch will return false */
}
+ }
- /* if escape ('\\'), just compare next character */
- if (c == '\\' && (c = *p++) == 0) /* if \ at end, then syntax error */
- return 0;
+#ifndef VMS /* No bracket matching in VMS */
+ /* Parse and process the list of characters and ranges in brackets */
+ if (!no_wild && allow_regex && c == '[')
+ {
+ int e; /* flag true if next char to be taken literally */
+ ZCONST char *q; /* pointer to end of [-] group */
+ int r; /* flag true to match anything but the range */
+
+ if (*s == 0) /* need a character to match */
+ return 0;
+ p += (r = (*p == '!' || *p == '^')); /* see if reverse */
+ for (q = p, e = 0; *q; q++) /* find closing bracket */
+ if (e)
+ e = 0;
+ else
+ if (*q == '\\')
+ e = 1;
+ else if (*q == ']')
+ break;
+ if (*q != ']') /* nothing matches if bad syntax */
+ return 0;
+ for (c = 0, e = *p == '-'; p < q; p++) /* go through the list */
+ {
+ if (e == 0 && *p == '\\') /* set escape flag if \ */
+ e = 1;
+ else if (e == 0 && *p == '-') /* set start of range if - */
+ c = *(p-1);
+ else
+ {
+ uch cc = (cs ? (uch)*s : case_map((uch)*s));
+ uch uc = (uch) c;
+ if (*(p+1) != '-')
+ for (uc = uc ? uc : (uch)*p; uc <= (uch)*p; uc++)
+ /* compare range */
+ if ((cs ? uc : case_map(uc)) == cc)
+ return r ? 0 : recmatch(q + CLEN(q), s + CLEN(s), cs);
+ c = e = 0; /* clear range, escape flags */
+ }
+ }
+ return r ? recmatch(q + CLEN(q), s + CLEN(s), cs) : 0;
+ /* bracket match failed */
+ }
+#endif /* !VMS */
- /* just a character--compare it */
-#ifdef QDOS
- return QMatch(Case((uch)c), Case(*s)) ?
- recmatch(p, s + CLEN(s), ic __WDL) : 0;
-#else
- return Case((uch)c) == Case(*s) ?
- recmatch(p, s + CLEN(s), ic __WDL) : 0;
-#endif
+ /* If escape ('\'), just compare next character */
+ if (!no_wild && c == '\\')
+ if ((c = *p++) == '\0') /* if \ at end, then syntax error */
+ return 0;
+
+#ifdef VMS
+ /* 2005-11-06 SMS.
+ Handle "..." wildcard in p with "." or "]" in s.
+ */
+ if ((c == '.') && (*p == '.') && (*(p+ CLEN( p)) == '.') &&
+ ((*s == '.') || (*s == ']')))
+ {
+ /* Match "...]" with "]". Continue after "]" in both. */
+ if ((*(p+ 2* CLEN( p)) == ']') && (*s == ']'))
+ return recmatch( (p+ 3* CLEN( p)), (s+ CLEN( s)), cs);
+
+ /* Else, look for a reduced match in s, until "]" in or end of s. */
+ for (; *s && (*s != ']'); INCSTR(s))
+ if (*s == '.')
+ /* If reduced match, then continue after "..." in p, "." in s. */
+ if ((c = recmatch( (p+ CLEN( p)), s, cs)) != 0)
+ return (int)c;
+
+ /* Match "...]" with "]". Continue after "]" in both. */
+ if ((*(p+ 2* CLEN( p)) == ']') && (*s == ']'))
+ return recmatch( (p+ 3* CLEN( p)), (s+ CLEN( s)), cs);
+
+ /* No reduced match. Quit. */
+ return 2;
+ }
+
+#endif /* def VMS */
+
+ /* Just a character--compare it */
+ return (cs ? c == *s : case_map((uch)c) == case_map((uch)*s)) ?
+ recmatch(p, s + CLEN(s), cs) : 0;
+}
-} /* end function recmatch() */
+/*************************************************************************************************/
static char *isshexp(p)
ZCONST char *p;
/* If p is a sh expression, a pointer to the first special character is

90
SOURCES/unzip-6.0-format-secure.patch

@ -0,0 +1,90 @@
diff --git a/extract.c b/extract.c
index eeb2f57..a0a4929 100644
--- a/extract.c
+++ b/extract.c
@@ -472,8 +472,8 @@ int extract_or_test_files(__G) /* return PK-type error code */
*/
Info(slide, 0x401, ((char *)slide,
LoadFarString(CentSigMsg), j + blknum*DIR_BLKSIZ + 1));
- Info(slide, 0x401, ((char *)slide,
- LoadFarString(ReportMsg)));
+ Info(slide, 0x401,
+ ((char *)slide,"%s", LoadFarString(ReportMsg)));
error_in_archive = PK_BADERR;
}
reached_end = TRUE; /* ...so no more left to do */
@@ -752,8 +752,8 @@ int extract_or_test_files(__G) /* return PK-type error code */
#ifndef SFX
if (no_endsig_found) { /* just to make sure */
- Info(slide, 0x401, ((char *)slide, LoadFarString(EndSigMsg)));
- Info(slide, 0x401, ((char *)slide, LoadFarString(ReportMsg)));
+ Info(slide, 0x401, ((char *)slide,"%s", LoadFarString(EndSigMsg)));
+ Info(slide, 0x401, ((char *)slide,"%s", LoadFarString(ReportMsg)));
if (!error_in_archive) /* don't overwrite stronger error */
error_in_archive = PK_WARN;
}
diff --git a/list.c b/list.c
index 15e0011..f7359c3 100644
--- a/list.c
+++ b/list.c
@@ -181,7 +181,7 @@ int list_files(__G) /* return PK-type error code */
Info(slide, 0x401,
((char *)slide, LoadFarString(CentSigMsg), j));
Info(slide, 0x401,
- ((char *)slide, LoadFarString(ReportMsg)));
+ ((char *)slide,"%s", LoadFarString(ReportMsg)));
return PK_BADERR; /* sig not found */
}
}
@@ -507,7 +507,8 @@ int list_files(__G) /* return PK-type error code */
&& (!G.ecrec.is_zip64_archive)
&& (memcmp(G.sig, end_central_sig, 4) != 0)
) { /* just to make sure again */
- Info(slide, 0x401, ((char *)slide, LoadFarString(EndSigMsg)));
+ Info(slide, 0x401,
+ ((char *)slide,"%s", LoadFarString(EndSigMsg)));
error_in_archive = PK_WARN; /* didn't find sig */
}
@@ -591,7 +592,7 @@ int get_time_stamp(__G__ last_modtime, nmember) /* return PK-type error code */
Info(slide, 0x401,
((char *)slide, LoadFarString(CentSigMsg), j));
Info(slide, 0x401,
- ((char *)slide, LoadFarString(ReportMsg)));
+ ((char *)slide,"%s", LoadFarString(ReportMsg)));
return PK_BADERR; /* sig not found */
}
}
@@ -674,7 +675,7 @@ int get_time_stamp(__G__ last_modtime, nmember) /* return PK-type error code */
---------------------------------------------------------------------------*/
if (memcmp(G.sig, end_central_sig, 4)) { /* just to make sure again */
- Info(slide, 0x401, ((char *)slide, LoadFarString(EndSigMsg)));
+ Info(slide, 0x401, ((char *)slide,"%s", LoadFarString(EndSigMsg)));
error_in_archive = PK_WARN;
}
if (*nmember == 0L && error_in_archive <= PK_WARN)
diff --git a/zipinfo.c b/zipinfo.c
index 6e22cc8..ac5c61b 100644
--- a/zipinfo.c
+++ b/zipinfo.c
@@ -771,7 +771,7 @@ int zipinfo(__G) /* return PK-type error code */
Info(slide, 0x401,
((char *)slide, LoadFarString(CentSigMsg), j));
Info(slide, 0x401,
- ((char *)slide, LoadFarString(ReportMsg)));
+ ((char *)slide,"%s", LoadFarString(ReportMsg)));
error_in_archive = PK_BADERR; /* sig not found */
break;
}
@@ -960,7 +960,8 @@ int zipinfo(__G) /* return PK-type error code */
&& (!G.ecrec.is_zip64_archive)
&& (memcmp(G.sig, end_central_sig, 4) != 0)
) { /* just to make sure again */
- Info(slide, 0x401, ((char *)slide, LoadFarString(EndSigMsg)));
+ Info(slide, 0x401,
+ ((char *)slide,"%s", LoadFarString(EndSigMsg)));
error_in_archive = PK_WARN; /* didn't find sig */
}

104
SOURCES/unzip-6.0-heap-overflow-infloop.patch

@ -0,0 +1,104 @@
From bdd4a0cecd745cb4825e4508b5bdf2579731086a Mon Sep 17 00:00:00 2001
From: Petr Stodulka <pstodulk@redhat.com>
Date: Mon, 14 Sep 2015 18:23:17 +0200
Subject: [PATCH 1/3] upstream fix for heap overflow

https://bugzilla.redhat.com/attachment.cgi?id=1073002
---
crypt.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/crypt.c b/crypt.c
index 784e411..a8975f2 100644
--- a/crypt.c
+++ b/crypt.c
@@ -465,7 +465,17 @@ int decrypt(__G__ passwrd)
GLOBAL(pInfo->encrypted) = FALSE;
defer_leftover_input(__G);
for (n = 0; n < RAND_HEAD_LEN; n++) {
- b = NEXTBYTE;
+ /* 2012-11-23 SMS. (OUSPG report.)
+ * Quit early if compressed size < HEAD_LEN. The resulting
+ * error message ("unable to get password") could be improved,
+ * but it's better than trying to read nonexistent data, and
+ * then continuing with a negative G.csize. (See
+ * fileio.c:readbyte()).
+ */
+ if ((b = NEXTBYTE) == (ush)EOF)
+ {
+ return PK_ERR;
+ }
h[n] = (uch)b;
Trace((stdout, " (%02x)", h[n]));
}
--
2.4.6


From 4b48844661ff9569f2ecf582a387d46a5775b5d8 Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Mon, 14 Sep 2015 18:24:56 +0200
Subject: [PATCH 2/3] fix infinite loop when extracting empty bzip2 data

Bug: https://sourceforge.net/p/infozip/patches/23/
---
extract.c | 6 ++++++
1 file changed, 6 insertions(+)

diff --git a/extract.c b/extract.c
index 7134bfe..29db027 100644
--- a/extract.c
+++ b/extract.c
@@ -2733,6 +2733,12 @@ __GDEF
int repeated_buf_err;
bz_stream bstrm;
+ if (G.incnt <= 0 && G.csize <= 0L) {
+ /* avoid an infinite loop */
+ Trace((stderr, "UZbunzip2() got empty input\n"));
+ return 2;
+ }
+
#if (defined(DLL) && !defined(NO_SLIDE_REDIR))
if (G.redirect_slide)
wsize = G.redirect_size, redirSlide = G.redirect_buffer;
--
2.4.6


From bd150334fb4084f5555a6be26b015a0671cb5b74 Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Tue, 22 Sep 2015 18:52:23 +0200
Subject: [PATCH 3/3] extract: prevent unsigned overflow on invalid input

Suggested-by: Stefan Cornelius
---
extract.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/extract.c b/extract.c
index 29db027..b9ae667 100644
--- a/extract.c
+++ b/extract.c
@@ -1257,8 +1257,17 @@ static int extract_or_test_entrylist(__G__ numchunk,
if (G.lrec.compression_method == STORED) {
zusz_t csiz_decrypted = G.lrec.csize;
- if (G.pInfo->encrypted)
+ if (G.pInfo->encrypted) {
+ if (csiz_decrypted < 12) {
+ /* handle the error now to prevent unsigned overflow */
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarStringSmall(ErrUnzipNoFile),
+ LoadFarString(InvalidComprData),
+ LoadFarStringSmall2(Inflate)));
+ return PK_ERR;
+ }
csiz_decrypted -= 12;
+ }
if (G.lrec.ucsize != csiz_decrypted) {
Info(slide, 0x401, ((char *)slide,
LoadFarStringSmall2(WrnStorUCSizCSizDiff),
--
2.5.2

11
SOURCES/unzip-6.0-manpage-fix.patch

@ -0,0 +1,11 @@
--- unzip60/man/unzip.1 2011-01-11 11:59:59.000000000 +0000
+++ unzip60/man/unzip_new 2011-02-05 18:45:55.000000000 +0000
@@ -424,7 +424,7 @@
.\" Amiga support possible eventually, but not yet
[MS-DOS, OS/2, NT] restore the volume label if the extraction medium is
removable (e.g., a diskette). Doubling the option (\fB\-$$\fP) allows fixed
-media (hard disks) to be labelled as well. By default, volume labels are
+media (hard disks) to be labeled as well. By default, volume labels are
ignored.
.IP \fB\-/\fP\ \fIextensions\fP
[Acorn only] overrides the extension list supplied by Unzip$Ext environment

34
SOURCES/unzip-6.0-overflow-long-fsize.patch

@ -0,0 +1,34 @@
diff --git a/list.c b/list.c
index f7359c3..4c3d703 100644
--- a/list.c
+++ b/list.c
@@ -97,7 +97,7 @@ int list_files(__G) /* return PK-type error code */
{
int do_this_file=FALSE, cfactor, error, error_in_archive=PK_COOL;
#ifndef WINDLL
- char sgn, cfactorstr[10];
+ char sgn, cfactorstr[13];
int longhdr=(uO.vflag>1);
#endif
int date_format;
@@ -339,7 +339,19 @@ int list_files(__G) /* return PK-type error code */
G.crec.compression_method == ENHDEFLATED) {
methbuf[5] = dtype[(G.crec.general_purpose_bit_flag>>1) & 3];
} else if (methnum >= NUM_METHODS) {
- sprintf(&methbuf[4], "%03u", G.crec.compression_method);
+ /* 2013-02-26 SMS.
+ * http://sourceforge.net/tracker/?func=detail
+ * &aid=2861648&group_id=118012&atid=679786
+ * Unexpectedly large compression methods overflow
+ * &methbuf[]. Use the old, three-digit decimal format
+ * for values which fit. Otherwise, sacrifice the
+ * colon, and use four-digit hexadecimal.
+ */
+ if (G.crec.compression_method <= 999) {
+ sprintf( &methbuf[ 4], "%03u", G.crec.compression_method);
+ } else {
+ sprintf( &methbuf[ 3], "%04X", G.crec.compression_method);
+ }
}
#if 0 /* GRR/Euro: add this? */

25
SOURCES/unzip-6.0-overflow.patch

@ -0,0 +1,25 @@
diff --git a/extract.c b/extract.c
index a0a4929..9ef80b3 100644
--- a/extract.c
+++ b/extract.c
@@ -2214,6 +2214,7 @@ static int test_compr_eb(__G__ eb, eb_size, compr_offset, test_uc_ebdata)
ulg eb_ucsize;
uch *eb_ucptr;
int r;
+ ush method;
if (compr_offset < 4) /* field is not compressed: */
return PK_OK; /* do nothing and signal OK */
@@ -2223,6 +2224,12 @@ static int test_compr_eb(__G__ eb, eb_size, compr_offset, test_uc_ebdata)
eb_size <= (compr_offset + EB_CMPRHEADLEN)))
return IZ_EF_TRUNC; /* no compressed data! */
+ method = makeword(eb + (EB_HEADSIZE + compr_offset));
+ if ((method == STORED) && (eb_size != compr_offset + EB_CMPRHEADLEN + eb_ucsize))
+ return PK_ERR; /* compressed & uncompressed
+ * should match in STORED
+ * method */
+
if (
#ifdef INT_16BIT
(((ulg)(extent)eb_ucsize) != eb_ucsize) ||

17
SOURCES/unzip-6.0-symlink.patch

@ -0,0 +1,17 @@
diff --git a/process.c b/process.c
index 1e9a1e1..905732b 100644
--- a/process.c
+++ b/process.c
@@ -1751,6 +1751,12 @@ int process_cdir_file_hdr(__G) /* return PK-type error code */
= (G.crec.general_purpose_bit_flag & (1 << 11)) == (1 << 11);
#endif
+#ifdef SYMLINKS
+ /* Initialize the symlink flag, may be set by the platform-specific
+ mapattr function. */
+ G.pInfo->symlink = 0;
+#endif
+
return PK_COOL;
} /* end function process_cdir_file_hdr() */

41
SOURCES/unzip-6.0-timestamp.patch

@ -0,0 +1,41 @@
From: "Steven M. Schweda" <sms@antinode.info>
Subject: Do not ignore extra fields containing Unix Timestamps
Bug-Debian: https://bugs.debian.org/842993
X-Debian-version: 6.0-21

--- a/process.c
+++ b/process.c
@@ -2914,10 +2914,13 @@
break;
case EF_IZUNIX2:
- if (have_new_type_eb == 0) {
- flags &= ~0x0ff; /* ignore any previous IZUNIX field */
+ if (have_new_type_eb == 0) { /* (< 1) */
have_new_type_eb = 1;
}
+ if (have_new_type_eb <= 1) {
+ /* Ignore any prior (EF_IZUNIX/EF_PKUNIX) UID/GID. */
+ flags &= 0x0ff;
+ }
#ifdef IZ_HAVE_UXUIDGID
if (have_new_type_eb > 1)
break; /* IZUNIX3 overrides IZUNIX2 e.f. block ! */
@@ -2933,6 +2936,8 @@
/* new 3rd generation Unix ef */
have_new_type_eb = 2;
+ /* Ignore any prior EF_IZUNIX/EF_PKUNIX/EF_IZUNIX2 UID/GID. */
+ flags &= 0x0ff;
/*
Version 1 byte version of this extra field, currently 1
UIDSize 1 byte Size of UID field
@@ -2953,8 +2958,6 @@
uid_size = *((EB_HEADSIZE + 1) + ef_buf);
gid_size = *((EB_HEADSIZE + uid_size + 2) + ef_buf);
- flags &= ~0x0ff; /* ignore any previous UNIX field */
-
if ( read_ux3_value((EB_HEADSIZE + 2) + ef_buf,
uid_size, &z_uidgid[0])
&&

26
SOURCES/unzip-6.0-valgrind.patch

@ -0,0 +1,26 @@
diff --git a/fileio.c b/fileio.c
index ba0a1d0..03fc4be 100644
--- a/fileio.c
+++ b/fileio.c
@@ -2006,6 +2006,7 @@ int do_string(__G__ length, option) /* return PK-type error code */
unsigned comment_bytes_left;
unsigned int block_len;
int error=PK_OK;
+ unsigned int length2;
#ifdef AMIGA
char tmp_fnote[2 * AMIGA_FILENOTELEN]; /* extra room for squozen chars */
#endif
@@ -2292,8 +2293,12 @@ int do_string(__G__ length, option) /* return PK-type error code */
seek_zipf(__G__ G.cur_zipfile_bufstart - G.extra_bytes +
(G.inptr-G.inbuf) + length);
} else {
- if (readbuf(__G__ (char *)G.extra_field, length) == 0)
+ if ((length2 = readbuf(__G__ (char *)G.extra_field, length)) == 0)
return PK_EOF;
+ if(length2 < length) {
+ memset (__G__ (char *)G.extra_field+length2, 0 , length-length2);
+ length = length2;
+ }
/* Looks like here is where extra fields are read */
getZip64Data(__G__ G.extra_field, length);
#ifdef UNICODE_SUPPORT

28
SOURCES/unzip-6.0-x-option.patch

@ -0,0 +1,28 @@
--- ./process.c.orig 2009-03-06 02:25:10.000000000 +0100
+++ ./process.c 2013-09-12 10:51:16.000000000 +0200
@@ -2901,9 +2901,9 @@
*/
#ifdef IZ_HAVE_UXUIDGID
- if (eb_len >= EB_UX3_MINLEN
- && z_uidgid != NULL
- && (*((EB_HEADSIZE + 0) + ef_buf) == 1)
+ if ((eb_len >= EB_UX3_MINLEN)
+ && (z_uidgid != NULL)
+ && ((*((EB_HEADSIZE + 0) + ef_buf) == 1)))
/* only know about version 1 */
{
uch uid_size;
@@ -2915,10 +2915,10 @@
flags &= ~0x0ff; /* ignore any previous UNIX field */
if ( read_ux3_value((EB_HEADSIZE + 2) + ef_buf,
- uid_size, z_uidgid[0])
+ uid_size, &z_uidgid[0])
&&
read_ux3_value((EB_HEADSIZE + uid_size + 3) + ef_buf,
- gid_size, z_uidgid[1]) )
+ gid_size, &z_uidgid[1]) )
{
flags |= EB_UX2_VALID; /* signal success */
}

25
SOURCES/unzip-zipbomb-manpage.patch

@ -0,0 +1,25 @@
From 6fe72291a5563cdbcd2bdd87e36528537b7cdcfb Mon Sep 17 00:00:00 2001
From: Jakub Martisko <jamartis@redhat.com>
Date: Mon, 18 Nov 2019 14:17:46 +0100
Subject: [PATCH] update the man page

---
man/unzip.1 | 2 ++
1 file changed, 2 insertions(+)

diff --git a/man/unzip.1 b/man/unzip.1
index 21816d1..4d66073 100644
--- a/man/unzip.1
+++ b/man/unzip.1
@@ -850,6 +850,8 @@ the specified zipfiles were not found.
invalid options were specified on the command line.
.IP 11
no matching files were found.
+.IP 12
+invalid zip file with overlapped components (possible zip-bomb). The zip-bomb checks can be disabled by using the UNZIP_DISABLE_ZIPBOMB_DETECTION=TRUE environment variable.
.IP 50
the disk is (or was) full during extraction.
.IP 51
--
2.23.0

25
SOURCES/unzip-zipbomb-part1.patch

@ -0,0 +1,25 @@
From 41beb477c5744bc396fa1162ee0c14218ec12213 Mon Sep 17 00:00:00 2001
From: Mark Adler <madler@alumni.caltech.edu>
Date: Mon, 27 May 2019 08:20:32 -0700
Subject: [PATCH] Fix bug in undefer_input() that misplaced the input state.

---
fileio.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/fileio.c b/fileio.c
index c042987..bc00d74 100644
--- a/fileio.c
+++ b/fileio.c
@@ -530,8 +530,10 @@ void undefer_input(__G)
* This condition was checked when G.incnt_leftover was set > 0 in
* defer_leftover_input(), and it is NOT allowed to touch G.csize
* before calling undefer_input() when (G.incnt_leftover > 0)
- * (single exception: see read_byte()'s "G.csize <= 0" handling) !!
+ * (single exception: see readbyte()'s "G.csize <= 0" handling) !!
*/
+ if (G.csize < 0L)
+ G.csize = 0L;
G.incnt = G.incnt_leftover + (int)G.csize;
G.inptr = G.inptr_leftover - (int)G.csize;
G.incnt_leftover = 0;

349
SOURCES/unzip-zipbomb-part2.patch

@ -0,0 +1,349 @@
From 47b3ceae397d21bf822bc2ac73052a4b1daf8e1c Mon Sep 17 00:00:00 2001
From: Mark Adler <madler@alumni.caltech.edu>
Date: Tue, 11 Jun 2019 22:01:18 -0700
Subject: [PATCH] Detect and reject a zip bomb using overlapped entries.

This detects an invalid zip file that has at least one entry that
overlaps with another entry or with the central directory to the
end of the file. A Fifield zip bomb uses overlapped local entries
to vastly increase the potential inflation ratio. Such an invalid
zip file is rejected.

See https://www.bamsoftware.com/hacks/zipbomb/ for David Fifield's
analysis, construction, and examples of such zip bombs.

The detection maintains a list of covered spans of the zip files
so far, where the central directory to the end of the file and any
bytes preceding the first entry at zip file offset zero are
considered covered initially. Then as each entry is decompressed
or tested, it is considered covered. When a new entry is about to
be processed, its initial offset is checked to see if it is
contained by a covered span. If so, the zip file is rejected as
invalid.

This commit depends on a preceding commit: "Fix bug in
undefer_input() that misplaced the input state."
---
extract.c | 190 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
globals.c | 1 +
globals.h | 3 +
process.c | 11 ++++
unzip.h | 1 +
5 files changed, 205 insertions(+), 1 deletion(-)

diff --git a/extract.c b/extract.c
index 1acd769..0973a33 100644
--- a/extract.c
+++ b/extract.c
@@ -319,6 +319,125 @@ static ZCONST char Far UnsupportedExtraField[] =
"\nerror: unsupported extra-field compression type (%u)--skipping\n";
static ZCONST char Far BadExtraFieldCRC[] =
"error [%s]: bad extra-field CRC %08lx (should be %08lx)\n";
+static ZCONST char Far NotEnoughMemCover[] =
+ "error: not enough memory for bomb detection\n";
+static ZCONST char Far OverlappedComponents[] =
+ "error: invalid zip file with overlapped components (possible zip bomb)\n";
+
+
+
+
+
+/* A growable list of spans. */
+typedef zoff_t bound_t;
+typedef struct {
+ bound_t beg; /* start of the span */
+ bound_t end; /* one past the end of the span */
+} span_t;
+typedef struct {
+ span_t *span; /* allocated, distinct, and sorted list of spans */
+ size_t num; /* number of spans in the list */
+ size_t max; /* allocated number of spans (num <= max) */
+} cover_t;
+
+/*
+ * Return the index of the first span in cover whose beg is greater than val.
+ * If there is no such span, then cover->num is returned.
+ */
+static size_t cover_find(cover, val)
+ cover_t *cover;
+ bound_t val;
+{
+ size_t lo = 0, hi = cover->num;
+ while (lo < hi) {
+ size_t mid = (lo + hi) >> 1;
+ if (val < cover->span[mid].beg)
+ hi = mid;
+ else
+ lo = mid + 1;
+ }
+ return hi;
+}
+
+/* Return true if val lies within any one of the spans in cover. */
+static int cover_within(cover, val)
+ cover_t *cover;
+ bound_t val;
+{
+ size_t pos = cover_find(cover, val);
+ return pos > 0 && val < cover->span[pos - 1].end;
+}
+
+/*
+ * Add a new span to the list, but only if the new span does not overlap any
+ * spans already in the list. The new span covers the values beg..end-1. beg
+ * must be less than end.
+ *
+ * Keep the list sorted and merge adjacent spans. Grow the allocated space for
+ * the list as needed. On success, 0 is returned. If the new span overlaps any
+ * existing spans, then 1 is returned and the new span is not added to the
+ * list. If the new span is invalid because beg is greater than or equal to
+ * end, then -1 is returned. If the list needs to be grown but the memory
+ * allocation fails, then -2 is returned.
+ */
+static int cover_add(cover, beg, end)
+ cover_t *cover;
+ bound_t beg;
+ bound_t end;
+{
+ size_t pos;
+ int prec, foll;
+
+ if (beg >= end)
+ /* The new span is invalid. */
+ return -1;
+
+ /* Find where the new span should go, and make sure that it does not
+ overlap with any existing spans. */
+ pos = cover_find(cover, beg);
+ if ((pos > 0 && beg < cover->span[pos - 1].end) ||
+ (pos < cover->num && end > cover->span[pos].beg))
+ return 1;
+
+ /* Check for adjacencies. */
+ prec = pos > 0 && beg == cover->span[pos - 1].end;
+ foll = pos < cover->num && end == cover->span[pos].beg;
+ if (prec && foll) {
+ /* The new span connects the preceding and following spans. Merge the
+ following span into the preceding span, and delete the following
+ span. */
+ cover->span[pos - 1].end = cover->span[pos].end;
+ cover->num--;
+ memmove(cover->span + pos, cover->span + pos + 1,
+ (cover->num - pos) * sizeof(span_t));
+ }
+ else if (prec)
+ /* The new span is adjacent only to the preceding span. Extend the end
+ of the preceding span. */
+ cover->span[pos - 1].end = end;
+ else if (foll)
+ /* The new span is adjacent only to the following span. Extend the
+ beginning of the following span. */
+ cover->span[pos].beg = beg;
+ else {
+ /* The new span has gaps between both the preceding and the following
+ spans. Assure that there is room and insert the span. */
+ if (cover->num == cover->max) {
+ size_t max = cover->max == 0 ? 16 : cover->max << 1;
+ span_t *span = realloc(cover->span, max * sizeof(span_t));
+ if (span == NULL)
+ return -2;
+ cover->span = span;
+ cover->max = max;
+ }
+ memmove(cover->span + pos + 1, cover->span + pos,
+ (cover->num - pos) * sizeof(span_t));
+ cover->num++;
+ cover->span[pos].beg = beg;
+ cover->span[pos].end = end;
+ }
+ return 0;
+}
@@ -374,6 +493,29 @@ int extract_or_test_files(__G) /* return PK-type error code */
}
#endif /* !SFX || SFX_EXDIR */
+ /* One more: initialize cover structure for bomb detection. Start with a
+ span that covers the central directory though the end of the file. */
+ if (G.cover == NULL) {
+ G.cover = malloc(sizeof(cover_t));
+ if (G.cover == NULL) {
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(NotEnoughMemCover)));
+ return PK_MEM;
+ }
+ ((cover_t *)G.cover)->span = NULL;
+ ((cover_t *)G.cover)->max = 0;
+ }
+ ((cover_t *)G.cover)->num = 0;
+ if ((G.extra_bytes != 0 &&
+ cover_add((cover_t *)G.cover, 0, G.extra_bytes) != 0) ||
+ cover_add((cover_t *)G.cover,
+ G.extra_bytes + G.ecrec.offset_start_central_directory,
+ G.ziplen) != 0) {
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(NotEnoughMemCover)));
+ return PK_MEM;
+ }
+
/*---------------------------------------------------------------------------
The basic idea of this function is as follows. Since the central di-
rectory lies at the end of the zipfile and the member files lie at the
@@ -591,7 +733,8 @@ int extract_or_test_files(__G) /* return PK-type error code */
if (error > error_in_archive)
error_in_archive = error;
/* ...and keep going (unless disk full or user break) */
- if (G.disk_full > 1 || error_in_archive == IZ_CTRLC) {
+ if (G.disk_full > 1 || error_in_archive == IZ_CTRLC ||
+ error == PK_BOMB) {
/* clear reached_end to signal premature stop ... */
reached_end = FALSE;
/* ... and cancel scanning the central directory */
@@ -1060,6 +1203,11 @@ static int extract_or_test_entrylist(__G__ numchunk,
/* seek_zipf(__G__ pInfo->offset); */
request = G.pInfo->offset + G.extra_bytes;
+ if (cover_within((cover_t *)G.cover, request)) {
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(OverlappedComponents)));
+ return PK_BOMB;
+ }
inbuf_offset = request % INBUFSIZ;
bufstart = request - inbuf_offset;
@@ -1591,6 +1739,18 @@ static int extract_or_test_entrylist(__G__ numchunk,
return IZ_CTRLC; /* cancel operation by user request */
}
#endif
+ error = cover_add((cover_t *)G.cover, request,
+ G.cur_zipfile_bufstart + (G.inptr - G.inbuf));
+ if (error < 0) {
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(NotEnoughMemCover)));
+ return PK_MEM;
+ }
+ if (error != 0) {
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(OverlappedComponents)));
+ return PK_BOMB;
+ }
#ifdef MACOS /* MacOS is no preemptive OS, thus call event-handling by hand */
UserStop();
#endif
@@ -1992,6 +2152,34 @@ static int extract_or_test_member(__G) /* return PK-type error code */
}
undefer_input(__G);
+
+ if ((G.lrec.general_purpose_bit_flag & 8) != 0) {
+ /* skip over data descriptor (harder than it sounds, due to signature
+ * ambiguity)
+ */
+# define SIG 0x08074b50
+# define LOW 0xffffffff
+ uch buf[12];
+ unsigned shy = 12 - readbuf((char *)buf, 12);
+ ulg crc = shy ? 0 : makelong(buf);
+ ulg clen = shy ? 0 : makelong(buf + 4);
+ ulg ulen = shy ? 0 : makelong(buf + 8); /* or high clen if ZIP64 */
+ if (crc == SIG && /* if not SIG, no signature */
+ (G.lrec.crc32 != SIG || /* if not SIG, have signature */
+ (clen == SIG && /* if not SIG, no signature */
+ ((G.lrec.csize & LOW) != SIG || /* if not SIG, have signature */
+ (ulen == SIG && /* if not SIG, no signature */
+ (G.zip64 ? G.lrec.csize >> 32 : G.lrec.ucsize) != SIG
+ /* if not SIG, have signature */
+ )))))
+ /* skip four more bytes to account for signature */
+ shy += 4 - readbuf((char *)buf, 4);
+ if (G.zip64)
+ shy += 8 - readbuf((char *)buf, 8); /* skip eight more for ZIP64 */
+ if (shy)
+ error = PK_ERR;
+ }
+
return error;
} /* end function extract_or_test_member() */
diff --git a/globals.c b/globals.c
index fa8cca5..1e0f608 100644
--- a/globals.c
+++ b/globals.c
@@ -181,6 +181,7 @@ Uz_Globs *globalsCtor()
# if (!defined(NO_TIMESTAMPS))
uO.D_flag=1; /* default to '-D', no restoration of dir timestamps */
# endif
+ G.cover = NULL; /* not allocated yet */
#endif
uO.lflag=(-1);
diff --git a/globals.h b/globals.h
index 11b7215..2bdcdeb 100644
--- a/globals.h
+++ b/globals.h
@@ -260,12 +260,15 @@ typedef struct Globals {
ecdir_rec ecrec; /* used in unzip.c, extract.c */
z_stat statbuf; /* used by main, mapname, check_for_newer */
+ int zip64; /* true if Zip64 info in extra field */
+
int mem_mode;
uch *outbufptr; /* extract.c static */
ulg outsize; /* extract.c static */
int reported_backslash; /* extract.c static */
int disk_full;
int newfile;
+ void **cover; /* used in extract.c for bomb detection */
int didCRlast; /* fileio static */
ulg numlines; /* fileio static: number of lines printed */
diff --git a/process.c b/process.c
index 1e9a1e1..d2e4dc3 100644
--- a/process.c
+++ b/process.c
@@ -637,6 +637,13 @@ void free_G_buffers(__G) /* releases all memory allocated in global vars */
}
#endif
+ /* Free the cover span list and the cover structure. */
+ if (G.cover != NULL) {
+ free(*(G.cover));
+ free(G.cover);
+ G.cover = NULL;
+ }
+
} /* end function free_G_buffers() */
@@ -1890,6 +1897,8 @@ int getZip64Data(__G__ ef_buf, ef_len)
#define Z64FLGS 0xffff
#define Z64FLGL 0xffffffff
+ G.zip64 = FALSE;
+
if (ef_len == 0 || ef_buf == NULL)
return PK_COOL;
@@ -1927,6 +1936,8 @@ int getZip64Data(__G__ ef_buf, ef_len)
#if 0
break; /* Expect only one EF_PKSZ64 block. */
#endif /* 0 */
+
+ G.zip64 = TRUE;
}

/* Skip this extra field block. */
diff --git a/unzip.h b/unzip.h
index 5b2a326..ed24a5b 100644
--- a/unzip.h
+++ b/unzip.h
@@ -645,6 +645,7 @@ typedef struct _Uzp_cdir_Rec {
#define PK_NOZIP 9 /* zipfile not found */
#define PK_PARAM 10 /* bad or illegal parameters specified */
#define PK_FIND 11 /* no files found */
+#define PK_BOMB 12 /* likely zip bomb */
#define PK_DISK 50 /* disk full */
#define PK_EOF 51 /* unexpected EOF */

112
SOURCES/unzip-zipbomb-part3.patch

@ -0,0 +1,112 @@
From 6d351831be705cc26d897db44f878a978f4138fc Mon Sep 17 00:00:00 2001
From: Mark Adler <madler@alumni.caltech.edu>
Date: Thu, 25 Jul 2019 20:43:17 -0700
Subject: [PATCH] Do not raise a zip bomb alert for a misplaced central
directory.

There is a zip-like file in the Firefox distribution, omni.ja,
which is a zip container with the central directory placed at the
start of the file instead of after the local entries as required
by the zip standard. This commit marks the actual location of the
central directory, as well as the end of central directory records,
as disallowed locations. This now permits such containers to not
raise a zip bomb alert, where in fact there are no overlaps.
---
extract.c | 25 +++++++++++++++++++------
process.c | 6 ++++++
unzpriv.h | 10 ++++++++++
3 files changed, 35 insertions(+), 6 deletions(-)

diff --git a/extract.c b/extract.c
index 0973a33..1b73cb0 100644
--- a/extract.c
+++ b/extract.c
@@ -493,8 +493,11 @@ int extract_or_test_files(__G) /* return PK-type error code */
}
#endif /* !SFX || SFX_EXDIR */
- /* One more: initialize cover structure for bomb detection. Start with a
- span that covers the central directory though the end of the file. */
+ /* One more: initialize cover structure for bomb detection. Start with
+ spans that cover any extra bytes at the start, the central directory,
+ the end of central directory record (including the Zip64 end of central
+ directory locator, if present), and the Zip64 end of central directory
+ record, if present. */
if (G.cover == NULL) {
G.cover = malloc(sizeof(cover_t));
if (G.cover == NULL) {
@@ -506,15 +509,25 @@ int extract_or_test_files(__G) /* return PK-type error code */
((cover_t *)G.cover)->max = 0;
}
((cover_t *)G.cover)->num = 0;
- if ((G.extra_bytes != 0 &&
- cover_add((cover_t *)G.cover, 0, G.extra_bytes) != 0) ||
- cover_add((cover_t *)G.cover,
+ if (cover_add((cover_t *)G.cover,
G.extra_bytes + G.ecrec.offset_start_central_directory,
- G.ziplen) != 0) {
+ G.extra_bytes + G.ecrec.offset_start_central_directory +
+ G.ecrec.size_central_directory) != 0) {
Info(slide, 0x401, ((char *)slide,
LoadFarString(NotEnoughMemCover)));
return PK_MEM;
}
+ if ((G.extra_bytes != 0 &&
+ cover_add((cover_t *)G.cover, 0, G.extra_bytes) != 0) ||
+ (G.ecrec.have_ecr64 &&
+ cover_add((cover_t *)G.cover, G.ecrec.ec64_start,
+ G.ecrec.ec64_end) != 0) ||
+ cover_add((cover_t *)G.cover, G.ecrec.ec_start,
+ G.ecrec.ec_end) != 0) {
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(OverlappedComponents)));
+ return PK_BOMB;
+ }
/*---------------------------------------------------------------------------
The basic idea of this function is as follows. Since the central di-
diff --git a/process.c b/process.c
index d2e4dc3..d75d405 100644
--- a/process.c
+++ b/process.c
@@ -1408,6 +1408,10 @@ static int find_ecrec64(__G__ searchlen) /* return PK-class error */
/* Now, we are (almost) sure that we have a Zip64 archive. */
G.ecrec.have_ecr64 = 1;
+ G.ecrec.ec_start -= ECLOC64_SIZE+4;
+ G.ecrec.ec64_start = ecrec64_start_offset;
+ G.ecrec.ec64_end = ecrec64_start_offset +
+ 12 + makeint64(&byterec[ECREC64_LENGTH]);
/* Update the "end-of-central-dir offset" for later checks. */
G.real_ecrec_offset = ecrec64_start_offset;
@@ -1542,6 +1546,8 @@ static int find_ecrec(__G__ searchlen) /* return PK-class error */
makelong(&byterec[OFFSET_START_CENTRAL_DIRECTORY]);
G.ecrec.zipfile_comment_length =
makeword(&byterec[ZIPFILE_COMMENT_LENGTH]);
+ G.ecrec.ec_start = G.real_ecrec_offset;
+ G.ecrec.ec_end = G.ecrec.ec_start + 22 + G.ecrec.zipfile_comment_length;
/* Now, we have to read the archive comment, BEFORE the file pointer
is moved away backwards to seek for a Zip64 ECLOC64 structure.
diff --git a/unzpriv.h b/unzpriv.h
index dc9eff5..297b3c7 100644
--- a/unzpriv.h
+++ b/unzpriv.h
@@ -2185,6 +2185,16 @@ typedef struct VMStimbuf {
int have_ecr64; /* valid Zip64 ecdir-record exists */
int is_zip64_archive; /* Zip64 ecdir-record is mandatory */
ush zipfile_comment_length;
+ zusz_t ec_start, ec_end; /* offsets of start and end of the
+ end of central directory record,
+ including if present the Zip64
+ end of central directory locator,
+ which immediately precedes the
+ end of central directory record */
+ zusz_t ec64_start, ec64_end; /* if have_ecr64 is true, then these
+ are the offsets of the start and
+ end of the Zip64 end of central
+ directory record */
} ecdir_rec;

25
SOURCES/unzip-zipbomb-part4.patch

@ -0,0 +1,25 @@
From 5e2efcd633a4a1fb95a129a75508e7d769e767be Mon Sep 17 00:00:00 2001
From: Mark Adler <madler@alumni.caltech.edu>
Date: Sun, 9 Feb 2020 20:36:28 -0800
Subject: [PATCH] Fix bug in UZbunzip2() that incorrectly updated G.incnt.

The update assumed a full buffer, which is not always full. This
could result in a false overlapped element detection when a small
bzip2-compressed file was unzipped. This commit remedies that.
---
extract.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/extract.c b/extract.c
index d9866f9..0cb7bfc 100644
--- a/extract.c
+++ b/extract.c
@@ -3010,7 +3010,7 @@ __GDEF
#endif
G.inptr = (uch *)bstrm.next_in;
- G.incnt = (G.inbuf + INBUFSIZ) - G.inptr; /* reset for other routines */
+ G.incnt -= G.inptr - G.inbuf; /* reset for other routines */
uzbunzip_cleanup_exit:
err = BZ2_bzDecompressEnd(&bstrm);

26
SOURCES/unzip-zipbomb-part5.patch

@ -0,0 +1,26 @@
From 5c572555cf5d80309a07c30cf7a54b2501493720 Mon Sep 17 00:00:00 2001
From: Mark Adler <madler@alumni.caltech.edu>
Date: Sun, 9 Feb 2020 21:39:09 -0800
Subject: [PATCH] Fix bug in UZinflate() that incorrectly updated G.incnt.

The update assumed a full buffer, which is not always full. This
could result in a false overlapped element detection when a small
deflate-compressed file was unzipped using an old zlib. This
commit remedies that.
---
inflate.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/inflate.c b/inflate.c
index 2f5a015..70e3cc0 100644
--- a/inflate.c
+++ b/inflate.c
@@ -700,7 +700,7 @@ int UZinflate(__G__ is_defl64)
G.dstrm.total_out));
G.inptr = (uch *)G.dstrm.next_in;
- G.incnt = (G.inbuf + INBUFSIZ) - G.inptr; /* reset for other routines */
+ G.incnt -= G.inptr - G.inbuf; /* reset for other routines */
uzinflate_cleanup_exit:
err = inflateReset(&G.dstrm);

95
SOURCES/unzip-zipbomb-part6.patch

@ -0,0 +1,95 @@
From 122050bac16fae82a460ff739fb1ca0f106e9d85 Mon Sep 17 00:00:00 2001
From: Mark Adler <madler@alumni.caltech.edu>
Date: Sat, 2 Jan 2021 13:09:34 -0800
Subject: [PATCH] Determine Zip64 status entry-by-entry instead of for entire
file.

Fixes a bug for zip files with mixed Zip64 and not Zip64 entries,
which resulted in an incorrect data descriptor length. The bug is
seen when a Zip64 entry precedes a non-Zip64 entry, in which case
the data descriptor would have been assumed to be larger than it
is, resulting in an incorrect bomb warning due to a perceived
overlap with the next entry. This commit determines and saves the
Zip64 status for each entry based on the central directory, and
then computes the length of each data descriptor accordingly.
---
extract.c | 5 +++--
globals.h | 2 --
process.c | 4 +---
unzpriv.h | 1 +
4 files changed, 5 insertions(+), 7 deletions(-)

diff --git a/extract.c b/extract.c
index 504afd6..878817d 100644
--- a/extract.c
+++ b/extract.c
@@ -658,6 +658,7 @@ int extract_or_test_files(__G) /* return PK-type error code */
break;
}
}
+ G.pInfo->zip64 = FALSE;
if ((error = do_string(__G__ G.crec.extra_field_length,
EXTRA_FIELD)) != 0)
{
@@ -2187,12 +2188,12 @@ static int extract_or_test_member(__G) /* return PK-type error code */
(clen == SIG && /* if not SIG, no signature */
((G.lrec.csize & LOW) != SIG || /* if not SIG, have signature */
(ulen == SIG && /* if not SIG, no signature */
- (G.zip64 ? G.lrec.csize >> 32 : G.lrec.ucsize) != SIG
+ (G.pInfo->zip64 ? G.lrec.csize >> 32 : G.lrec.ucsize) != SIG
/* if not SIG, have signature */
)))))
/* skip four more bytes to account for signature */
shy += 4 - readbuf((char *)buf, 4);
- if (G.zip64)
+ if (G.pInfo->zip64)
shy += 8 - readbuf((char *)buf, 8); /* skip eight more for ZIP64 */
if (shy)
error = PK_ERR;
diff --git a/globals.h b/globals.h
index f9c6daf..a883c90 100644
--- a/globals.h
+++ b/globals.h
@@ -261,8 +261,6 @@ typedef struct Globals {
ecdir_rec ecrec; /* used in unzip.c, extract.c */
z_stat statbuf; /* used by main, mapname, check_for_newer */
- int zip64; /* true if Zip64 info in extra field */
-
int mem_mode;
uch *outbufptr; /* extract.c static */
ulg outsize; /* extract.c static */
diff --git a/process.c b/process.c
index d75d405..d643c6f 100644
--- a/process.c
+++ b/process.c
@@ -1903,8 +1903,6 @@ int getZip64Data(__G__ ef_buf, ef_len)
#define Z64FLGS 0xffff
#define Z64FLGL 0xffffffff
- G.zip64 = FALSE;
-
if (ef_len == 0 || ef_buf == NULL)
return PK_COOL;
@@ -1943,7 +1941,7 @@ int getZip64Data(__G__ ef_buf, ef_len)
break; /* Expect only one EF_PKSZ64 block. */
#endif /* 0 */
- G.zip64 = TRUE;
+ G.pInfo->zip64 = TRUE;
}
/* Skip this extra field block. */
diff --git a/unzpriv.h b/unzpriv.h
index 09f288e..75b3359 100644
--- a/unzpriv.h
+++ b/unzpriv.h
@@ -2034,6 +2034,7 @@ typedef struct min_info {
#ifdef UNICODE_SUPPORT
unsigned GPFIsUTF8: 1; /* crec gen_purpose_flag UTF-8 bit 11 is set */
#endif
+ unsigned zip64: 1; /* true if entry has Zip64 extra block */
#ifndef SFX
char Far *cfilname; /* central header version of filename */
#endif

200
SOURCES/unzip-zipbomb-switch.patch

@ -0,0 +1,200 @@
From 5b44c818b96193b3e240f38f61985fa2bc780eb7 Mon Sep 17 00:00:00 2001
From: Jakub Martisko <jamartis@redhat.com>
Date: Tue, 30 Nov 2021 15:42:17 +0100
Subject: [PATCH] Add an option to disable the zipbomb detection

This can be done by settting a newly introduced environment variable
UNZIP_DISABLE_ZIPBOMB_DETECTION to {TRUE,True,true}. If the variable is unset, or
set to any other value the zipbomb detection is left enabled.

Example:
UNZIP_DISABLE_ZIPBOMB_DETECTION=True unzip ./zbsm.zip -d ./test
---
extract.c | 85 ++++++++++++++++++++++++++++++-------------------------
unzip.c | 15 ++++++++--
unzip.h | 1 +
3 files changed, 60 insertions(+), 41 deletions(-)

diff --git a/extract.c b/extract.c
index 878817d..3e58071 100644
--- a/extract.c
+++ b/extract.c
@@ -322,7 +322,8 @@ static ZCONST char Far BadExtraFieldCRC[] =
static ZCONST char Far NotEnoughMemCover[] =
"error: not enough memory for bomb detection\n";
static ZCONST char Far OverlappedComponents[] =
- "error: invalid zip file with overlapped components (possible zip bomb)\n";
+ "error: invalid zip file with overlapped components (possible zip bomb)\n \
+To unzip the file anyway, rerun the command with UNZIP_DISABLE_ZIPBOMB_DETECTION=TRUE environmnent variable\n";
@@ -502,35 +503,37 @@ int extract_or_test_files(__G) /* return PK-type error code */
the end of central directory record (including the Zip64 end of central
directory locator, if present), and the Zip64 end of central directory
record, if present. */
- if (G.cover == NULL) {
+ if (uO.zipbomb == TRUE) {
+ if (G.cover == NULL) {
G.cover = malloc(sizeof(cover_t));
if (G.cover == NULL) {
- Info(slide, 0x401, ((char *)slide,
- LoadFarString(NotEnoughMemCover)));
- return PK_MEM;
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString(NotEnoughMemCover)));
+ return PK_MEM;
}
((cover_t *)G.cover)->span = NULL;
((cover_t *)G.cover)->max = 0;
- }
- ((cover_t *)G.cover)->num = 0;
- if (cover_add((cover_t *)G.cover,
- G.extra_bytes + G.ecrec.offset_start_central_directory,
- G.extra_bytes + G.ecrec.offset_start_central_directory +
- G.ecrec.size_central_directory) != 0) {
+ }
+ ((cover_t *)G.cover)->num = 0;
+ if (cover_add((cover_t *)G.cover,
+ G.extra_bytes + G.ecrec.offset_start_central_directory,
+ G.extra_bytes + G.ecrec.offset_start_central_directory +
+ G.ecrec.size_central_directory) != 0) {
Info(slide, 0x401, ((char *)slide,
- LoadFarString(NotEnoughMemCover)));
+ LoadFarString(NotEnoughMemCover)));
return PK_MEM;
- }
- if ((G.extra_bytes != 0 &&
- cover_add((cover_t *)G.cover, 0, G.extra_bytes) != 0) ||
- (G.ecrec.have_ecr64 &&
- cover_add((cover_t *)G.cover, G.ecrec.ec64_start,
- G.ecrec.ec64_end) != 0) ||
- cover_add((cover_t *)G.cover, G.ecrec.ec_start,
- G.ecrec.ec_end) != 0) {
+ }
+ if ((G.extra_bytes != 0 &&
+ cover_add((cover_t *)G.cover, 0, G.extra_bytes) != 0) ||
+ (G.ecrec.have_ecr64 &&
+ cover_add((cover_t *)G.cover, G.ecrec.ec64_start,
+ G.ecrec.ec64_end) != 0) ||
+ cover_add((cover_t *)G.cover, G.ecrec.ec_start,
+ G.ecrec.ec_end) != 0) {
Info(slide, 0x401, ((char *)slide,
- LoadFarString(OverlappedComponents)));
+ LoadFarString(OverlappedComponents)));
return PK_BOMB;
+ }
}
/*---------------------------------------------------------------------------
@@ -1222,10 +1225,12 @@ static int extract_or_test_entrylist(__G__ numchunk,
/* seek_zipf(__G__ pInfo->offset); */
request = G.pInfo->offset + G.extra_bytes;
- if (cover_within((cover_t *)G.cover, request)) {
+ if (uO.zipbomb == TRUE) {
+ if (cover_within((cover_t *)G.cover, request)) {
Info(slide, 0x401, ((char *)slide,
- LoadFarString(OverlappedComponents)));
+ LoadFarString(OverlappedComponents)));
return PK_BOMB;
+ }
}
inbuf_offset = request % INBUFSIZ;
bufstart = request - inbuf_offset;
@@ -1758,17 +1763,19 @@ reprompt:
return IZ_CTRLC; /* cancel operation by user request */
}
#endif
- error = cover_add((cover_t *)G.cover, request,
- G.cur_zipfile_bufstart + (G.inptr - G.inbuf));
- if (error < 0) {
+ if (uO.zipbomb == TRUE) {
+ error = cover_add((cover_t *)G.cover, request,
+ G.cur_zipfile_bufstart + (G.inptr - G.inbuf));
+ if (error < 0) {
Info(slide, 0x401, ((char *)slide,
- LoadFarString(NotEnoughMemCover)));
+ LoadFarString(NotEnoughMemCover)));
return PK_MEM;
- }
- if (error != 0) {
+ }
+ if (error != 0) {
Info(slide, 0x401, ((char *)slide,
- LoadFarString(OverlappedComponents)));
+ LoadFarString(OverlappedComponents)));
return PK_BOMB;
+ }
}
#ifdef MACOS /* MacOS is no preemptive OS, thus call event-handling by hand */
UserStop();
@@ -2171,8 +2178,8 @@ static int extract_or_test_member(__G) /* return PK-type error code */
}
undefer_input(__G);
-
- if ((G.lrec.general_purpose_bit_flag & 8) != 0) {
+ if (uO.zipbomb == TRUE) {
+ if ((G.lrec.general_purpose_bit_flag & 8) != 0) {
/* skip over data descriptor (harder than it sounds, due to signature
* ambiguity)
*/
@@ -2189,6 +2196,7 @@ static int extract_or_test_member(__G) /* return PK-type error code */
shy += 8 - readbuf((char *)buf, 8); /* skip eight more for ZIP64 */
if (shy)
error = PK_ERR;
+ }
}
return error;
diff --git a/unzip.c b/unzip.c
index 8dbfc95..abb3644 100644
--- a/unzip.c
+++ b/unzip.c
@@ -1329,10 +1329,9 @@ int uz_opts(__G__ pargc, pargv)
int *pargc;
char ***pargv;
{
- char **argv, *s;
+ char **argv, *s, *zipbomb_envar;
int argc, c, error=FALSE, negative=0, showhelp=0;
-
argc = *pargc;
argv = *pargv;
@@ -1923,6 +1922,18 @@ opts_done: /* yes, very ugly...but only used by UnZipSFX with -x xlist */
else
G.extract_flag = TRUE;
+ /* Disable the zipbomb detection, this is the only option set only via the shell variables but it should at least not clash with something in the future. */
+ zipbomb_envar = getenv("UNZIP_DISABLE_ZIPBOMB_DETECTION");
+ uO.zipbomb = TRUE;
+ if (zipbomb_envar != NULL) {
+ /* strcasecmp might be a better approach here but it is POSIX-only */
+ if ((strcmp ("TRUE", zipbomb_envar) == 0)
+ || (strcmp ("True", zipbomb_envar) == 0)
+ || (strcmp ("true",zipbomb_envar) == 0)) {
+ uO.zipbomb = FALSE;
+ }
+ }
+
*pargc = argc;
*pargv = argv;
return PK_OK;
diff --git a/unzip.h b/unzip.h
index ed24a5b..e7665e8 100644
--- a/unzip.h
+++ b/unzip.h
@@ -559,6 +559,7 @@ typedef struct _UzpOpts {
#ifdef UNIX
int cflxflag; /* -^: allow control chars in extracted filenames */
#endif
+ int zipbomb;
#endif /* !FUNZIP */
} UzpOpts;
--
2.33.0

632
SPECS/unzip.spec

@ -0,0 +1,632 @@

# Settings for EL <= 7
%if 0%{?rhel} && 0%{?rhel} <= 7
%{!?__global_ldflags: %global __global_ldflags -Wl,-z,relro}
%endif

Summary: A utility for unpacking zip files
Name: unzip
Version: 6.0
Release: 56%{?dist}
License: BSD
Source: http://downloads.sourceforge.net/infozip/unzip60.tar.gz

# Not sent to upstream.
Patch1: unzip-6.0-bzip2-configure.patch
# Upstream plans to do this in zip (hopefully also in unzip).
Patch2: unzip-6.0-exec-shield.patch
# Upstream plans to do similar thing.
Patch3: unzip-6.0-close.patch
# Details in rhbz#532380.
# Reported to upstream: http://www.info-zip.org/board/board.pl?m-1259575993/
Patch4: unzip-6.0-attribs-overflow.patch
# Not sent to upstream, as it's Fedora/RHEL specific.
# Modify the configure script to accept var LFLAGS2 so linking can be configurable
# from the spec file. In addition '-s' is still removed as before
Patch5: unzip-6.0-configure.patch
Patch6: unzip-6.0-manpage-fix.patch
# Update match.c with recmatch() from zip 3.0's util.c
# This also resolves the license issue in that old function.
# Original came from here: https://projects.parabolagnulinux.org/abslibre.git/plain/libre/unzip-libre/match.patch
Patch7: unzip-6.0-fix-recmatch.patch
# Update process.c
Patch8: unzip-6.0-symlink.patch
# change using of macro "case_map" by "to_up"
Patch9: unzip-6.0-caseinsensitive.patch
# downstream fix for "-Werror=format-security"
# upstream doesn't want hear about this option again
Patch10: unzip-6.0-format-secure.patch

Patch11: unzip-6.0-valgrind.patch
Patch12: unzip-6.0-x-option.patch
Patch13: unzip-6.0-overflow.patch
Patch14: unzip-6.0-cve-2014-8139.patch
Patch15: unzip-6.0-cve-2014-8140.patch
Patch16: unzip-6.0-cve-2014-8141.patch
Patch17: unzip-6.0-overflow-long-fsize.patch

# Fix heap overflow and infinite loop when invalid input is given (#1260947)
Patch18: unzip-6.0-heap-overflow-infloop.patch

# support non-{latin,unicode} encoding
Patch19: unzip-6.0-alt-iconv-utf8.patch
Patch20: unzip-6.0-alt-iconv-utf8-print.patch
Patch21: 0001-Fix-CVE-2016-9844-rhbz-1404283.patch

# restore unix timestamp accurately
Patch22: unzip-6.0-timestamp.patch

# fix possible heap based stack overflow in passwd protected files
Patch23: unzip-6.0-cve-2018-1000035-heap-based-overflow.patch

Patch24: unzip-6.0-cve-2018-18384.patch

# covscan issues
Patch25: unzip-6.0-COVSCAN-fix-unterminated-string.patch

Patch26: unzip-zipbomb-part1.patch
Patch27: unzip-zipbomb-part2.patch
Patch28: unzip-zipbomb-part3.patch
Patch29: unzip-zipbomb-manpage.patch
Patch30: unzip-zipbomb-part4.patch
Patch31: unzip-zipbomb-part5.patch
Patch32: unzip-zipbomb-part6.patch
Patch33: unzip-zipbomb-switch.patch

URL: http://www.info-zip.org/UnZip.html
BuildRequires: make
BuildRequires: bzip2-devel, gcc

%description
The unzip utility is used to list, test, or extract files from a zip
archive. Zip archives are commonly found on MS-DOS systems. The zip
utility, included in the zip package, creates zip archives. Zip and
unzip are both compatible with archives created by PKWARE(R)'s PKZIP
for MS-DOS, but the programs' options and default behaviors do differ
in some respects.

Install the unzip package if you need to list, test or extract files from
a zip archive.

%prep
%setup -q -n unzip60
%patch1 -p1
%patch2 -p1
%patch3 -p1
%patch4 -p1
%patch5 -p1
%patch6 -p1
%patch7 -p1
%patch8 -p1
%patch9 -p1
%patch10 -p1
%patch11 -p1
%patch12 -p1
%patch13 -p1
%patch14 -p1
%patch15 -p1
%patch16 -p1
%patch17 -p1
%patch18 -p1
%patch19 -p1
%patch20 -p1
%patch21 -p1
%patch22 -p1
%patch23 -p1
%patch24 -p1
%patch25 -p1

%patch26 -p1
%patch27 -p1
%patch28 -p1
%patch29 -p1
%patch30 -p1
%patch31 -p1
%patch32 -p1
%patch33 -p1

%build
# Use the C implementation of CRC instead of assembly (only on i386, other architectures use C by default)
sed -i -e 's:-DASM_CRC::g' unix/configure
sed -i -e 's:CRC32OA="crc_gcc.o":CRC32OA="":g' unix/configure

# IZ_HAVE_UXUIDGID is needed for right functionality of unzip -X
# NOMEMCPY solve problem with memory overlapping - decomression is slowly,
# but successfull.
%make_build -f unix/Makefile CF_NOOPT="-I. -DUNIX $RPM_OPT_FLAGS -DNOMEMCPY -DIZ_HAVE_UXUIDGID -DNO_LCHMOD" \
LFLAGS2="%{?__global_ldflags}" generic_gcc

%install
rm -rf $RPM_BUILD_ROOT
make -f unix/Makefile prefix=$RPM_BUILD_ROOT%{_prefix} MANDIR=$RPM_BUILD_ROOT/%{_mandir}/man1 INSTALL="cp -p" install

%files
%license LICENSE COPYING.OLD
%doc README BUGS
%{_bindir}/*
%{_mandir}/*/*

%changelog
* Wed Jan 26 2022 Jakub Martisko <jamartis@redhat.com> - 6.0-56
- Use the C crc implementation instead of the asm (i686 only, other arches already use C)
Related: rhbz#2045075

* Wed Jan 05 2022 Jakub Martisko <jamartis@redhat.com> - 6.0-55
- Rebuild with the gating tests enabled
Related: rhbz#2036946

* Mon Dec 20 2021 Jakub Martisko <jamartis@redhat.com> - 6.0-54
- Add an environment variable that disables the zipbomb detection
Resolves: rhbz#2031730

* Tue Aug 10 2021 Mohan Boddu <mboddu@redhat.com> - 6.0-53
- Rebuilt for IMA sigs, glibc 2.34, aarch64 flags
Related: rhbz#1991688

* Fri Apr 30 2021 Jakub Martisko <jamartis@redhat.com> - 6.0-52
- Add several patches dealing with false positice zipbomb detection
Resolves: #1954651

* Fri Apr 16 2021 Mohan Boddu <mboddu@redhat.com> - 6.0-51
- Rebuilt for RHEL 9 BETA on Apr 15th 2021. Related: rhbz#1947937

* Wed Jan 27 2021 Fedora Release Engineering <releng@fedoraproject.org> - 6.0-50
- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild

* Wed Jul 29 2020 Fedora Release Engineering <releng@fedoraproject.org> - 6.0-49
- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild

* Tue Jul 14 2020 Tom Stellard <tstellar@redhat.com> - 6.0-48
- Use make macros
- https://fedoraproject.org/wiki/Changes/UseMakeBuildInstallMacro

* Fri Jan 31 2020 Fedora Release Engineering <releng@fedoraproject.org> - 6.0-47
- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild

* Mon Nov 18 2019 Jakub Martisko <jamartis@redhat.com> - 6.0-46
- Mention the zipbomb exit code in the manpage
Related: CVE-2019-13232

* Wed Oct 23 2019 Jakub Martisko <jamartis@redhat.com> - 6.0-45
- Fix possible zipbomb in unzip
Resolves: CVE-2019-13232

* Sat Jul 27 2019 Fedora Release Engineering <releng@fedoraproject.org> - 6.0-44
- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild

* Sun Feb 03 2019 Fedora Release Engineering <releng@fedoraproject.org> - 6.0-43
- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild

* Thu Nov 08 2018 Jakub Martisko <jamartis@redhat.com> - 6.0-42
- fix several possibly unterminated strings
When copying to OEM_CP and ISO_CP strings, the string could end unterminated
(stncpy does not append '\0').

* Thu Nov 08 2018 Jakub Martisko <jamartis@redhat.com> - 6.0-41
- Fix CVE-2018-18384
Resolves: CVE-2018-18384

* Sat Jul 14 2018 Fedora Release Engineering <releng@fedoraproject.org> - 6.0-40
- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild

* Thu Mar 01 2018 Jakub Martisko <jamartis@redhat.com> - 6.0-39
- Add gcc to buildrequires

* Tue Feb 13 2018 Jakub Martisko <jamartis@redhat.com> - 6.0-38
- Fix CVE-2018-1000035 - heap based buffer overflow when opening
password protected files.
Resolves: 1537043

* Fri Feb 09 2018 Fedora Release Engineering <releng@fedoraproject.org> - 6.0-37
- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild

* Thu Aug 03 2017 Fedora Release Engineering <releng@fedoraproject.org> - 6.0-36
- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild

* Thu Jul 27 2017 Fedora Release Engineering <releng@fedoraproject.org> - 6.0-35
- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild

* Fri Jul 14 2017 Petr Stodulka <pstodulk@redhat.com> - 6.0.34
- restore of unix timestamp accurately
Resolves: #1451953

* Sat Feb 11 2017 Fedora Release Engineering <releng@fedoraproject.org> - 6.0-33
- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild

* Wed Feb 01 2017 Stephen Gallagher <sgallagh@redhat.com> - 6.0-32
- Add missing %%license macro

* Wed Dec 14 2016 Petr Stodulka <pstodulk@redhat.com> - 6.0-31
- Fix CVE-2016-9844 - buffer overflow in zipinfo
Resolves: #1404283

* Thu Jul 14 2016 Petr Stodulka <pstodulk@redhat.com> - 6.0-30
- rename patch unzip-6.0-nostrip.patch to unzip-6.0-configure.patch
so linking is now configurable from the spec file
- define __global_ldflags on EL <= 7
- set LFLAGS2 with __global_ldflags for hardened build
Resolves: #1330519

* Fri Jul 01 2016 Petr Stodulka <pstodulk@redhat.com> - 6.0-29
- added build parameter "-DNO_LCHMOD" because lchmod isn't provided on Linux
system
Resolves: #1350627

* Fri Feb 05 2016 Fedora Release Engineering <releng@fedoraproject.org> - 6.0-28
- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild

* Wed Nov 25 2015 Petr Stodulka <pstodulk@redhat.com> - 6.0-27
- fix print of non-ascii filenames (#225576)

* Fri Nov 13 2015 Petr Stodulka <pstodulk@redhat.com> - 6.0-26
- fix unsigned overflow patch for #1260944 (#1281804)

* Thu Oct 29 2015 Petr Stodulka <pstodulk@redhat.com> - 6.0-25
- add support of non-latin and non-unicode encodings for filenames (#885540)

* Wed Sep 23 2015 Kamil Dudka <kdudka@redhat.com> - 6.0-24
- prevent unsigned overflow on invalid input (#1260944)

* Mon Sep 14 2015 Kamil Dudka <kdudka@redhat.com> - 6.0-23
- Fix heap overflow and infinite loop when invalid input is given (#1260947)

* Fri Jun 19 2015 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 6.0-22
- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild

* Sat Feb 21 2015 Till Maas <opensource@till.name> - 6.0-21
- Rebuilt for Fedora 23 Change
https://fedoraproject.org/wiki/Changes/Harden_all_packages_with_position-independent_code

* Wed Feb 11 2015 Petr Stodulka <pstodulk@redhat.com> - 6.0-20
- re-patch CVE-2014-9636 - original patch was incorrect (#1184986)

* Tue Feb 10 2015 Petr Stodulka <pstodulk@redhat.com> - 6.0-19
- Fix CVE-2014-8139 - CRC32 verification heap-based buffer overread
(#1174844)
- Fix CVE-2014-8140 - out-of-bounds write issue in test_compr_eb()
(#1174851)
- Fix CVE-2014-8141 - getZip64Data() out-of-bounds read issues
(#1174856)
- Fix buffer overflow on long file sizes
(#1191136)

* Mon Jan 26 2015 Petr Stodulka <pstodulk@redhat.com> - 6.0-18
- Fix security bug - CVE-2014-9636

* Fri Nov 21 2014 Petr Stodulka <pstodulk@redhat.com> - 6.0-17
- Fix unitialized reads (#558738)
- Fix fix broken -X option - never worked before. Added -DIZ_HAVE_UXUIDGID
option for compilation.
(#935202)

* Thu Nov 06 2014 Petr Stodulka <pstodulk@redhat.com> - 6.0-16
- Fix producing of incorrect output due to memcpy overlapping
by added option -D NOMEMCPY to compile section.
(#1153388)

* Mon Aug 18 2014 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 6.0-15
- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild

* Fri Jun 06 2014 Petr Stodulka <pstodulk@redhat.com> - 6.0-14
- Fix previous patch (#1104018) - case-insensitive matching
was reversed in function recmatch

* Wed Jun 04 2014 Petr Stodulka <pstodulk@redhat.com> - 6.0-13
- Solve problem with non-functional case-insensitive matching
(#1104018)
- Added patch for build option "-Werror=format-security"
However solve only false positives - here is not really
vulnerable print.

* Mon Oct 21 2013 Petr Stodulka <pstodulk@redhat.com> - 6.0.-12
- Solve problem with symlink errors in archive with many files
(#740012,#972427)

* Sun Aug 04 2013 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 6.0-11
- Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild

* Mon Jun 24 2013 Tom Callaway <spot@fedoraproject.org> - 6.0-10
- unset WILD_STOP_AT_DIR

* Tue May 28 2013 Tom Callaway <spot@fedoraproject.org> - 6.0-9
- Apply changes to match.c to sync with recmatch from util.c (from zip 3.0)
This also resolves the license issue in that file.

* Fri Feb 15 2013 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 6.0-8
- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild

* Mon Dec 10 2012 Michal Luscon <mluscon@redhat.com> 6.0-7
- Resolves: #884679 - zip files with bzip2 compression

* Sun Jul 22 2012 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 6.0-6
- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild

* Sat Jan 14 2012 Fedora Release Engineering <rel-eng@lists.fedoraproject.org>
- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild

- Fix minor manpage spelling mistake
Resolves: #675454

* Mon Feb 07 2011 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 6.0-4
- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild

* Mon May 24 2010 Karel Klic <kklic@redhat.com> - 6.0-3
- Removed BuildRoot tag
- Removed %%clean section
- Removed trailing whitespaces in the spec file

* Mon Nov 30 2009 Karel Klic <kklic@redhat.com> - 6.0-2
- Fixed a buffer overflow (rhbz#532380, unzip-6.0-attribs-overflow.patch)
- Generate debuginfos (rhbz#540220, unzip-6.0-nostrip.patch)

* Mon Nov 16 2009 Karel Klic <kklic@redhat.com> - 6.0-1
- New upstream version
- Compiled using `make generic_gcc` (includes asm)
- Removed unzip542-rpmoptflags.patch, because RPM_OPT_FLAGS
are provided using command line
- Removed unzip-5.51-link-segv.patch, because the link file
is not reopened in the current version
- Removed unzip-5.51-link-segv2.patch, the bug was already fixed
in open_outfile in 5.52
- Removed unzip-5.52-toctou.patch (CAN-2005-2475), the vulnerability
is fixed in the current version
- Removed unzip-5.52-near-4GB.patch, unzip-5.52-near-4GB2.patch,
unzip-5.52-4GB3.patch, and unzip-5.52-4GB_types.patch, because
the current version supports large files
- Removed unzip-5.52-long-filename.patch, the current version
fixes the vulnerability by checking the length of command line
arguments in unzip.c
- Removed unzip-5.52-makefile.patch, because we no longer create
the link manually
- Removed unzip-5.52-open.patch, the current version uses umask.
- Removed unzip-5.52-cve-2008-0888.patch, the current version
fixes this vulnerability
- Ported unzip-5.52-249057.patch to current version (unzip-6.0-close)

* Sun Jul 26 2009 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 5.52-11
- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild

* Wed Feb 25 2009 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 5.52-10
- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild

* Wed Mar 19 2008 Ivana Varekova <varekova@redhat.com> - 5.52-9
- fix crash (double free) on malformed zip archive
CVE-2008-0888 (#431438)

* Fri Feb 8 2008 Ivana Varekova <varekova@redhat.com> - 5.52-8
- fix output when out of space error appears

* Wed Jan 23 2008 Ivana Varekova <varekova@redhat.com> - 5.52-7
- fix another long file support problem

* Tue Jan 22 2008 Ivana Varekova <varekova@redhat.com> - 5.52-6
- add 4GB patch (#429674)

* Tue Sep 4 2007 Ivana Varekova <varekova@redhat.com> - 5.52-5
- fix open call

* Wed Feb 7 2007 Ivana Varekova <varekova@redhat.com> - 5.52-4
- incorporate the next peckage review comment

* Tue Feb 6 2007 Ivana Varekova <varekova@redhat.com> - 5.52-3
- Resolves: 226516
Incorporate the package review

* Wed Jul 12 2006 Jesse Keating <jkeating@redhat.com> - 5.52-2.2.1
- rebuild

* Fri Feb 10 2006 Jesse Keating <jkeating@redhat.com> - 5.52-2.2
- bump again for double-long bug on ppc(64)

* Tue Feb 07 2006 Jesse Keating <jkeating@redhat.com> - 5.52-2.1
- rebuilt for new gcc4.1 snapshot and glibc changes

* Mon Feb 6 2006 Ivana Varekova <varekova@redhat.com> 5.52-2
- fix bug 180078 - unzip -l causing error
- fix CVE-2005-4667 - unzip long file name buffer overflow

* Thu Dec 22 2005 Ivana Varekova <varekova@redhat.com> 5.52-1
- update to 5.52

* Fri Dec 09 2005 Jesse Keating <jkeating@redhat.com>
- rebuilt

* Wed Aug 3 2005 Ivana Varekova <varekova@redhat.com> 5.51-12
- fix bug 164928 - TOCTOU issue in unzip

* Mon May 9 2005 Ivana Varekova <varekova@redhat.com> 5.51-11
- fix bug 156959 – invalid file mode on created files

* Mon Mar 7 2005 Ivana Varekova <varekova@redhat.com> 5.51-10
- rebuilt

* Thu Feb 10 2005 Ivana Varekova <varekova@redhat.com> 5.51-9
- fix the other problem with unpacking zipfiles containing symlinks
(bug #134073)

* Thu Feb 03 2005 Ivana Varekova <varekova@redhat.com> 5.51-8
- fix segfault with unpacking of zipfiles containing dangling symlinks
(bug #134073)

* Thu Dec 02 2004 Lon Hohberger <lhh@redhat.com> 5.51-6
- Rebuild

* Thu Dec 02 2004 Lon Hohberger <lhh@redhat.com> 5.51-5
- Fix segfault on extraction of symlinks

* Mon Jun 21 2004 Lon Hohberger <lhh@redhat.com> 5.51-4
- Extend max file/archive size to 2^32-8193 (4294959103) bytes

* Tue Jun 15 2004 Elliot Lee <sopwith@redhat.com>
- rebuilt

* Tue Jun 08 2004 Lon Hohberger <lhh@redhat.com> 5.51-2
- Rebuild

* Tue Jun 08 2004 Lon Hohberger <lhh@redhat.com> 5.51-1.1
- Update to 5.51; remove dotdot patch.

* Fri Feb 13 2004 Elliot Lee <sopwith@redhat.com>
- rebuilt

* Mon Nov 17 2003 Lon Hohberger <lhh@redhat.com> 5.50-36
- Rebuild for FC-next

* Fri Aug 01 2003 Lon Hohberger <lhh@redhat.com> 5.50-35
- Rebuild for Severn

* Fri Aug 01 2003 Lon Hohberger <lhh@redhat.com> 5.50-34
- Rebuild for Taroon

* Fri Aug 01 2003 Lon Hohberger <lhh@redhat.com> 5.50-33
- Rebuild for 9 errata

* Fri Aug 01 2003 Lon Hohberger <lhh@redhat.com> 5.50-32
- Rebuild for 8.0 errata

* Fri Aug 01 2003 Lon Hohberger <lhh@redhat.com> 5.50-31
- Rebuild for 7.3 errata

* Wed Jul 30 2003 Lon Hohberger <lhh@redhat.com> 5.50-30
- SECURITY Round 3: Fix up original patch (from 5.50-9) to fix
^V/ exploit, but still allow '-:', which the other patch (5.50-18)
does not allow. Never allow explicit writing to the root
directory; force users to change there and extract it manually.

* Wed Jul 30 2003 Lon Hohberger <lhh@redhat.com> 5.50-29
- Rebuild for Severn

* Wed Jul 30 2003 Lon Hohberger <lhh@redhat.com> 5.50-28
- Rebuild

* Wed Jul 30 2003 Lon Hohberger <lhh@redhat.com> 5.50-27
- Rebuild for 9

* Wed Jul 30 2003 Lon Hohberger <lhh@redhat.com> 5.50-26
- Rebuild for 8.0

* Tue Jul 22 2003 Lon Hohberger <lhh@redhat.com> 5.50-23
- Rebuild for 7.3

* Mon Jul 21 2003 Lon Hohberger <lhh@redhat.com> 5.50-22
- Rebuild for Severn

* Mon Jul 21 2003 Lon Hohberger <lhh@redhat.com> 5.50-21
- Rebuild

* Mon Jul 21 2003 Lon Hohberger <lhh@redhat.com> 5.50-20
- Rebuild for 9

* Mon Jul 21 2003 Lon Hohberger <lhh@redhat.com> 5.50-19
- Rebuild for 8.0

* Mon Jul 21 2003 Lon Hohberger <lhh@redhat.com> 5.50-18
- SECURITY: Incorporate far cleaner patch from Ben Laurie
<ben@algroup.co.uk> which also fixes ^V/ (quote-slash).
Patch checks post-decode as opposed to inline as previous
patch does.

* Mon Jun 16 2003 Lon Hohberger <lhh@redhat.com> 5.50-17
- Rebuilt per request

* Thu Jun 12 2003 Lon Hohberger <lhh@redhat.com> 5.50-16
- Rebuilt

* Thu Jun 12 2003 Lon Hohberger <lhh@redhat.com> 5.50-15
- Rebuilt

* Thu Jun 12 2003 Lon Hohberger <lhh@redhat.com> 5.50-14
- Rebuilt: Red Hat Linux 9

* Thu Jun 12 2003 Lon Hohberger <lhh@redhat.com> 5.50-13
- Rebuilt: Red Hat Enterprise Linux 2.1

* Thu Jun 12 2003 Lon Hohberger <lhh@redhat.com> 5.50-12
- Rebuilt Red Hat Linux 8.0

* Thu Jun 12 2003 Lon Hohberger <lhh@redhat.com> 5.50-11
- Rebuilt Red Hat Linux 7.3

* Wed Jun 11 2003 Lon Hohberger <lhh@redhat.com> 5.50-10
- Rebuilt

* Wed Jun 11 2003 Lon Hohberger <lhh@redhat.com> 5.50-9
- SECURITY: Scour start of filename for ../ patterns which
include quote and/or control characters.

* Wed Jun 04 2003 Elliot Lee <sopwith@redhat.com>
- rebuilt

* Wed Jan 22 2003 Tim Powers <timp@redhat.com>
- rebuilt

* Thu Dec 19 2002 Tim Powers <timp@redhat.com>
- bump and rebuild

* Fri Jun 21 2002 Tim Powers <timp@redhat.com>
- automated rebuild

* Thu May 23 2002 Tim Powers <timp@redhat.com>
- automated rebuild

* Thu Apr 25 2002 Trond Eivind Glomsrød <teg@redhat.com> 5.50-3
- Rebuild

* Tue Apr 2 2002 Trond Eivind Glomsrød <teg@redhat.com> 5.50-2
- Make it not strip

* Wed Mar 13 2002 Trond Eivind Glomsrød <teg@redhat.com> 5.50-1
- 5.50

* Thu Feb 21 2002 Trond Eivind Glomsrød <teg@redhat.com> 5.42-3
- Rebuild

* Wed Jan 09 2002 Tim Powers <timp@redhat.com>
- automated rebuild

* Mon May 21 2001 Trond Eivind Glomsrød <teg@redhat.com>
- 5.42
- Don't strip binaries explicitly
- build without assembly, it doesn't seem to increase performance
- make it respect RPM_OPT_FLAGS, define _GNU_SOURCE
- use %%{_tmppath}
- "License:" replaces "Copyright:"
- Update URL
- include zipgrep
- COPYING doesn't exist anymore, include LICENSE instead

* Thu Jul 13 2000 Prospector <bugzilla@redhat.com>
- automatic rebuild

* Sun Jun 11 2000 BIll Nottingham <notting@redhat.com>
- rebuild in new env.; FHS fixes.

* Tue Apr 18 2000 Bernhard Rosenkraenzer <bero@redhat.com>
- 4.51 (an acceptable license at last...)

* Thu Feb 3 2000 Bill Nottingham <notting@redhat.com>
- handle compressed man pages

* Fri Jul 30 1999 Bill Nottingham <notting@redhat.com>
- update to 5.40

* Sun Mar 21 1999 Cristian Gafton <gafton@redhat.com>
- auto rebuild in the new build environment (release 5)

* Thu Dec 17 1998 Michael Maher <mike@redhat.com>
- built for 6.0

* Tue Aug 11 1998 Jeff Johnson <jbj@redhat.com>
- build root

* Mon Apr 27 1998 Prospector System <bugs@redhat.com>
- translations modified for de, fr, tr

* Tue Oct 21 1997 Erik Troan <ewt@redhat.com>
- builds on non i386 platforms

* Mon Oct 20 1997 Otto Hammersmith <otto@redhat.com>
- updated the version

* Thu Jul 10 1997 Erik Troan <ewt@redhat.com>
- built against glibc
Loading…
Cancel
Save