From 90b9a63919e917879bfa36e4734b0c18c668d106 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Nov 03 2016 05:43:58 +0000 Subject: import unzip-6.0-16.el7 --- diff --git a/SOURCES/unzip-6.0-alt-iconv-utf8-print.patch b/SOURCES/unzip-6.0-alt-iconv-utf8-print.patch new file mode 100644 index 0000000..0b0153b --- /dev/null +++ b/SOURCES/unzip-6.0-alt-iconv-utf8-print.patch @@ -0,0 +1,381 @@ +From ca0212ba19b64488b9e8459a762c11ecd6e7d0bd Mon Sep 17 00:00:00 2001 +From: Petr Stodulka +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 ++# include + # endif + # endif + # ifndef _MBCS /* no need to include 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 + diff --git a/SOURCES/unzip-6.0-alt-iconv-utf8.patch b/SOURCES/unzip-6.0-alt-iconv-utf8.patch new file mode 100644 index 0000000..aa8970e --- /dev/null +++ b/SOURCES/unzip-6.0-alt-iconv-utf8.patch @@ -0,0 +1,400 @@ +From: Giovanni Scafora +Subject: unzip files encoded with non-latin, non-unicode file names +Last-Update: 2015-02-11 + +Updated 2015-02-11 by Marc Deslauriers +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 ++#include ++ + #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 ++ ++#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,12 +327,23 @@ + -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\ + -U use escapes for all non-ASCII Unicode\n\ + -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\ ++ -U use escapes for all non-ASCII Unicode\n\ ++ -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; diff --git a/SOURCES/unzip-6.0-format-secure.patch b/SOURCES/unzip-6.0-format-secure.patch new file mode 100644 index 0000000..81cf860 --- /dev/null +++ b/SOURCES/unzip-6.0-format-secure.patch @@ -0,0 +1,90 @@ +diff --git a/extract.c b/extract.c +index eeb2f57..a0a4929 100644 +--- a/extract.c ++++ b/extract.c +@@ -472,8 +472,8 @@ int extract_or_test_files(__G) /* return PK-type error code */ + */ + Info(slide, 0x401, ((char *)slide, + LoadFarString(CentSigMsg), j + blknum*DIR_BLKSIZ + 1)); +- Info(slide, 0x401, ((char *)slide, +- LoadFarString(ReportMsg))); ++ Info(slide, 0x401, ++ ((char *)slide,"%s", LoadFarString(ReportMsg))); + error_in_archive = PK_BADERR; + } + reached_end = TRUE; /* ...so no more left to do */ +@@ -752,8 +752,8 @@ int extract_or_test_files(__G) /* return PK-type error code */ + + #ifndef SFX + if (no_endsig_found) { /* just to make sure */ +- Info(slide, 0x401, ((char *)slide, LoadFarString(EndSigMsg))); +- Info(slide, 0x401, ((char *)slide, LoadFarString(ReportMsg))); ++ Info(slide, 0x401, ((char *)slide,"%s", LoadFarString(EndSigMsg))); ++ Info(slide, 0x401, ((char *)slide,"%s", LoadFarString(ReportMsg))); + if (!error_in_archive) /* don't overwrite stronger error */ + error_in_archive = PK_WARN; + } +diff --git a/list.c b/list.c +index 15e0011..f7359c3 100644 +--- a/list.c ++++ b/list.c +@@ -181,7 +181,7 @@ int list_files(__G) /* return PK-type error code */ + Info(slide, 0x401, + ((char *)slide, LoadFarString(CentSigMsg), j)); + Info(slide, 0x401, +- ((char *)slide, LoadFarString(ReportMsg))); ++ ((char *)slide,"%s", LoadFarString(ReportMsg))); + return PK_BADERR; /* sig not found */ + } + } +@@ -507,7 +507,8 @@ int list_files(__G) /* return PK-type error code */ + && (!G.ecrec.is_zip64_archive) + && (memcmp(G.sig, end_central_sig, 4) != 0) + ) { /* just to make sure again */ +- Info(slide, 0x401, ((char *)slide, LoadFarString(EndSigMsg))); ++ Info(slide, 0x401, ++ ((char *)slide,"%s", LoadFarString(EndSigMsg))); + error_in_archive = PK_WARN; /* didn't find sig */ + } + +@@ -591,7 +592,7 @@ int get_time_stamp(__G__ last_modtime, nmember) /* return PK-type error code */ + Info(slide, 0x401, + ((char *)slide, LoadFarString(CentSigMsg), j)); + Info(slide, 0x401, +- ((char *)slide, LoadFarString(ReportMsg))); ++ ((char *)slide,"%s", LoadFarString(ReportMsg))); + return PK_BADERR; /* sig not found */ + } + } +@@ -674,7 +675,7 @@ int get_time_stamp(__G__ last_modtime, nmember) /* return PK-type error code */ + ---------------------------------------------------------------------------*/ + + if (memcmp(G.sig, end_central_sig, 4)) { /* just to make sure again */ +- Info(slide, 0x401, ((char *)slide, LoadFarString(EndSigMsg))); ++ Info(slide, 0x401, ((char *)slide,"%s", LoadFarString(EndSigMsg))); + error_in_archive = PK_WARN; + } + if (*nmember == 0L && error_in_archive <= PK_WARN) +diff --git a/zipinfo.c b/zipinfo.c +index 6e22cc8..ac5c61b 100644 +--- a/zipinfo.c ++++ b/zipinfo.c +@@ -771,7 +771,7 @@ int zipinfo(__G) /* return PK-type error code */ + Info(slide, 0x401, + ((char *)slide, LoadFarString(CentSigMsg), j)); + Info(slide, 0x401, +- ((char *)slide, LoadFarString(ReportMsg))); ++ ((char *)slide,"%s", LoadFarString(ReportMsg))); + error_in_archive = PK_BADERR; /* sig not found */ + break; + } +@@ -960,7 +960,8 @@ int zipinfo(__G) /* return PK-type error code */ + && (!G.ecrec.is_zip64_archive) + && (memcmp(G.sig, end_central_sig, 4) != 0) + ) { /* just to make sure again */ +- Info(slide, 0x401, ((char *)slide, LoadFarString(EndSigMsg))); ++ Info(slide, 0x401, ++ ((char *)slide,"%s", LoadFarString(EndSigMsg))); + error_in_archive = PK_WARN; /* didn't find sig */ + } + diff --git a/SOURCES/unzip-6.0-symlink.patch b/SOURCES/unzip-6.0-symlink.patch new file mode 100644 index 0000000..d7eaf16 --- /dev/null +++ b/SOURCES/unzip-6.0-symlink.patch @@ -0,0 +1,17 @@ +diff --git a/process.c b/process.c +index 1e9a1e1..905732b 100644 +--- a/process.c ++++ b/process.c +@@ -1751,6 +1751,12 @@ int process_cdir_file_hdr(__G) /* return PK-type error code */ + = (G.crec.general_purpose_bit_flag & (1 << 11)) == (1 << 11); + #endif + ++#ifdef SYMLINKS ++ /* Initialize the symlink flag, may be set by the platform-specific ++ mapattr function. */ ++ G.pInfo->symlink = 0; ++#endif ++ + return PK_COOL; + + } /* end function process_cdir_file_hdr() */ diff --git a/SPECS/unzip.spec b/SPECS/unzip.spec index 017ae2a..8ef5aa1 100644 --- a/SPECS/unzip.spec +++ b/SPECS/unzip.spec @@ -1,7 +1,7 @@ Summary: A utility for unpacking zip files Name: unzip Version: 6.0 -Release: 15%{?dist} +Release: 16%{?dist} License: BSD Group: Applications/Archiving Source: http://downloads.sourceforge.net/infozip/unzip60.tar.gz @@ -30,6 +30,17 @@ Patch10: unzip-6.0-cve-2014-9636.patch Patch11: unzip-6.0-cve-2014-8139.patch Patch12: unzip-6.0-cve-2014-8140.patch Patch13: unzip-6.0-cve-2014-8141.patch +Patch14: unzip-6.0-format-secure.patch +Patch15: unzip-6.0-alt-iconv-utf8.patch +Patch16: unzip-6.0-alt-iconv-utf8-print.patch +Patch17: unzip-6.0-symlink.patch + +#Patch14: unzip-6.0-alt-iconv-utf8.patch +#Patch15: unzip-6.0-symlink.patch +#Patch16: unzip-6.0-format-secure.patch +#Patch17: unzip-6.0-alt-iconv-utf8-print.patch + + URL: http://www.info-zip.org/UnZip.html BuildRequires: bzip2-devel @@ -59,7 +70,10 @@ a zip archive. %patch11 -p1 -b .cve-2014-8139.patch %patch12 -p1 -b .cve-2014-8140.patch %patch13 -p1 -b .cve-2014-8141.patch - +%patch14 -p1 -b .wformat +%patch15 -p1 -b .utf +%patch16 -p1 -b .utf-print +%patch17 -p1 -b .symlink %build make -f unix/Makefile CF_NOOPT="-I. -DUNIX $RPM_OPT_FLAGS" generic_gcc %{?_smp_mflags} @@ -75,6 +89,14 @@ make -f unix/Makefile prefix=$RPM_BUILD_ROOT%{_prefix} MANDIR=$RPM_BUILD_ROOT/%{ %{_mandir}/*/* %changelog +* Wed Nov 25 2015 Petr Stodulka - 6.0-16 +- Added patch for build option "-Werror=format-security" +- Added support of non-unicode non-latin charset +- Fix print of non-ascii filenames +- Fix troubles with symlinks for archives with many files + Resolves: rhbz#1276746, rhbz#1286165, rhbz#1276744 + + * Wed Feb 25 2015 Petr Stodulka - 6.0-15 - Fix CVE-2014-9636 CVE-2014-8139 CVE-2014-8140 CVE-2014-8141 Resolves: #1196134 #1196122 #1196126 #1196130