Toshaan Bharvani
2 years ago
commit
7736687e84
34 changed files with 3973 additions and 0 deletions
@ -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 |
||||||
|
|
@ -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 |
||||||
|
|
@ -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 |
||||||
|
|
@ -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; |
@ -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] = { |
@ -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 |
||||||
|
|
||||||
|
|
@ -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; |
||||||
|
} |
||||||
|
|
||||||
|
|
@ -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 */ |
@ -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='' |
@ -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 */ |
||||||
|
|
||||||
|
|
@ -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)) |
@ -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); |
||||||
|
} |
@ -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); |
@ -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"), |
@ -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 |
@ -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 |
@ -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 */ |
||||||
|
} |
||||||
|
|
@ -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 |
||||||
|
|
@ -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 |
@ -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? */ |
@ -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) || |
@ -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() */ |
@ -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]) |
||||||
|
&& |
@ -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 |
@ -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 */ |
||||||
|
} |
@ -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 |
||||||
|
|
@ -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; |
@ -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 */ |
||||||
|
|
@ -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; |
||||||
|
|
||||||
|
|
@ -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); |
@ -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); |
@ -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 |
@ -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 |
||||||
|
|
@ -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…
Reference in new issue