code:
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


code:
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;

repo_name: dustdfg/dragora

license: mit


code:
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] = {


code:
--- unzip60/unix/configure.orig	2009-04-16 16:25:12.000000000 -0300
+++ unzip60/unix/configure	2017-05-14 18:53:49.000000000 -0300
@@ -640,7 +640,24 @@
     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


code:
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;
 }


code:
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 */


code:
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=''


code:
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 */


code:
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))


code:
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);
     }


code:
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


code:
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 */
         }


code:
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


code:
--- unzip60/man/unzip.1.orig	2009-04-19 21:33:10.000000000 -0300
+++ unzip60/man/unzip.1	2017-05-18 02:27:24.000000000 -0300
@@ -495,7 +495,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


code:
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? */


code:
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) ||


code:
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() */


code:
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


code:
--- unzip60/process.c.orig	2009-03-05 23:25:10.000000000 -0200
+++ unzip60/process.c	2017-05-18 14:47:34.000000000 -0300
@@ -2895,9 +2895,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;
@@ -2909,10 +2909,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 */
                 }


code:
patch taken from sabotage linux -- https://github.com/rofl0r/sabotage
diff -aur util-linux-2.23.1.org/fdisks/cfdisk.c util-linux-2.23.1/fdisks/cfdisk.c
--- util-linux-2.23.1.org/fdisks/cfdisk.c	2013-07-01 21:37:58.508000002 +0000
+++ util-linux-2.23.1/fdisks/cfdisk.c	2013-07-01 22:00:23.042000002 +0000
@@ -325,7 +325,7 @@
 int logical = 0;
 long long logical_sectors[MAXIMUM_PARTS];

-__sighandler_t old_SIGINT, old_SIGTERM;
+sighandler_t old_SIGINT, old_SIGTERM;

 int arrow_cursor = FALSE;
 int display_units = MEGABYTES;
diff -aur util-linux-2.23.1.org/fdisks/fdisksunlabel.c util-linux-2.23.1/fdisks/fdisksunlabel.c
--- util-linux-2.23.1.org/fdisks/fdisksunlabel.c	2013-07-01 21:37:58.508000002 +0000
+++ util-linux-2.23.1/fdisks/fdisksunlabel.c	2013-07-01 21:59:43.721000002 +0000
@@ -383,9 +383,11 @@
 	}
 }

-static int verify_sun_cmp(int *a, int *b, void *data)
+static void* cmp_data;
+static int verify_sun_cmp(const void *pa, const void *pb)
 {
-    unsigned int *verify_sun_starts = (unsigned int *) data;
+    const int *a = pa, *b = pb;
+    unsigned int *verify_sun_starts = (unsigned int *) cmp_data;

     if (*a == -1)
 	    return 1;
@@ -449,9 +451,8 @@
         else
             array[i] = -1;
     }
-    qsort_r(array,ARRAY_SIZE(array),sizeof(array[0]),
-	  (int (*)(const void *,const void *,void *)) verify_sun_cmp,
-	  verify_sun_starts);
+    cmp_data = verify_sun_starts;
+    qsort(array,ARRAY_SIZE(array),sizeof(array[0]), verify_sun_cmp);

     if (array[0] == -1) {
 	fdisk_info(cxt, _("No partitions defined"));
diff -aur util-linux-2.23.1.org/include/ttyutils.h util-linux-2.23.1/include/ttyutils.h
--- util-linux-2.23.1.org/include/ttyutils.h	2013-05-27 10:45:06.000000000 -0300
+++ util-linux-2.23.1/include/ttyutils.h	2013-07-05 12:19:54.000000000 -0300
@@ -10,6 +10,7 @@
 #include <stdlib.h>
 #include <termios.h>
 #include <limits.h>
+#include <sys/ttydefaults.h>
 #ifdef HAVE_SYS_IOCTL_H
 #include <sys/ioctl.h>
 #endif
diff -aur util-linux-2.23.1.org/term-utils/setterm.c util-linux-2.23.1/term-utils/setterm.c
--- util-linux-2.23.1.org/term-utils/setterm.c	2013-07-01 21:37:58.442000002 +0000
+++ util-linux-2.23.1/term-utils/setterm.c	2013-07-01 22:02:54.244000002 +0000
@@ -123,7 +123,7 @@
 #include "nls.h"
 #include "closestream.h"

-#if __GNU_LIBRARY__ < 5
+#if defined(__GLIBC__) && __GNU_LIBRARY__ < 5
 #ifndef __alpha__
 # include <linux/unistd.h>
 #define __NR_klogctl __NR_syslog
diff -aur util-linux-2.23.1.org/term-utils/ttymsg.c util-linux-2.23.1/term-utils/ttymsg.c
--- util-linux-2.23.1.org/term-utils/ttymsg.c	2013-07-01 21:37:58.442000002 +0000
+++ util-linux-2.23.1/term-utils/ttymsg.c	2013-07-01 22:07:02.788000002 +0000
@@ -41,6 +41,7 @@
   */

 #include <sys/types.h>
+#include <sys/param.h>
 #include <sys/uio.h>
 #include <signal.h>
 #include <fcntl.h>
diff -aur util-linux-2.23.1.org/text-utils/hexdump.h util-linux-2.23.1/text-utils/hexdump.h
--- util-linux-2.23.1.org/text-utils/hexdump.h	2013-07-01 21:37:58.437000002 +0000
+++ util-linux-2.23.1/text-utils/hexdump.h	2013-07-01 22:01:27.005000002 +0000
@@ -32,7 +32,7 @@
  *
  *	@(#)hexdump.h	5.4 (Berkeley) 6/1/90
  */
-
+#include <sys/types.h>
 typedef struct _pr {
 	struct _pr *nextpr;		/* next print unit */
 #define	F_ADDRESS	0x001		/* print offset */
diff -aur util-linux-2.23.1.org/text-utils/pg.c util-linux-2.23.1/text-utils/pg.c
--- util-linux-2.23.1.org/text-utils/pg.c	2013-07-01 21:37:58.437000002 +0000
+++ util-linux-2.23.1/text-utils/pg.c	2013-07-01 22:01:55.831000002 +0000
@@ -37,7 +37,7 @@
 #ifndef	TIOCGWINSZ
 # include <sys/ioctl.h>
 #endif
-#include <sys/termios.h>
+#include <termios.h>
 #include <fcntl.h>
 #include <regex.h>
 #include <stdio.h>


code:
--- docs/Makefile.in.orig	2017-06-15 10:41:30.000000000 -0300
+++ docs/Makefile.in	2017-08-28 12:01:05.802707671 -0300
@@ -665,8 +665,8 @@
 install-data-hook:
 	set -e; \
 	if test -r html ; then \
-		mkdir -p $(DESTDIR)$(datadir)/doc/valgrind; \
-		cp -r html $(DESTDIR)$(datadir)/doc/valgrind; \
+		mkdir -p $(DESTDIR)$(docdir); \
+		cp -r html $(DESTDIR)$(docdir); \
 	fi
 	for f in *.1 ; do \
 		if test -r $$f ; then \
@@ -677,13 +677,13 @@
  ifeq ($(BUILD_ALL_DOCS),yes)
 	set -e; \
 	if test -r index.pdf ; then \
-		mkdir -p $(DESTDIR)$(datadir)/doc/valgrind; \
-		cp index.pdf $(DESTDIR)$(datadir)/doc/valgrind/valgrind_manual.pdf; \
+		mkdir -p $(DESTDIR)$(docdir); \
+		cp index.pdf $(DESTDIR)$(docdir)/valgrind_manual.pdf; \
 	fi
 	set -e; \
 	if test -r index.ps ; then \
-		mkdir -p $(DESTDIR)$(datadir)/doc/valgrind; \
-		cp index.ps $(DESTDIR)$(datadir)/doc/valgrind/valgrind_manual.ps; \
+		mkdir -p $(DESTDIR)$(docdir); \
+		cp index.ps $(DESTDIR)$(docdir)/valgrind_manual.ps; \
 	fi
  endif


code:
From bc78aa61cfbddaa27dee275f639ba40de6981b17 Mon Sep 17 00:00:00 2001
From: George V. Kouryachy (Fr. Br. George) <george@altlinux.ru>
Date: Fri, 4 Aug 2017 18:37:33 +0300
Subject: [PATCH] parse_displayname: use FamilyWild for *:0

---
 xauth/gethost.c  |    4 ++++
 xauth/parsedpy.c |    4 ++++
 2 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/xauth/gethost.c b/xauth/gethost.c
index 8cb58c5..598ac48 100644
--- a/xauth/gethost.c
+++ b/xauth/gethost.c
@@ -180,6 +180,10 @@ struct addrlist *get_address_info (
      * information to be copied and set len to the number of bytes.
      */
     switch (family) {
+      case FamilyWild:			/* was :0 */
+	src = "\xff\xff";
+	len = strlen(src);
+	break;
       case FamilyLocal:			/* hostname/unix:0 */
 					/* handle unix:0 and :0 specially */
 	if (prefix == 0 && (strncmp (fulldpyname, "unix:", 5) == 0 ||
diff --git a/xauth/parsedpy.c b/xauth/parsedpy.c
index 97988d3..6c98339 100644
--- a/xauth/parsedpy.c
+++ b/xauth/parsedpy.c
@@ -141,6 +141,10 @@ parse_displayname (const char *displayname,
 	    family = FamilyInternet;
 	}
 #endif
+    } else if (len == 1 && *displayname == '*') {
+	/* ALT: wildcard cookie */
+	host = copystring("*", 1);
+	family = FamilyWild;
     } else if (!dnet && (*displayname == '[') && (*(ptr - 1) == ']')) {
 	/* Allow RFC2732-like [<IPv6NumericAddress>]:display syntax */
 	family = FamilyInternet6;
--
1.7.3.3


code:
From 4730f13b9261a00b87b3e98f070d100d8d72bef7 Mon Sep 17 00:00:00 2001
From: Tuomo Rinne <tuomo.rinne@pm.me>
Date: Mon, 14 Jan 2019 22:33:42 +0000
Subject: Fix build error when building with xserver built using meson

---
 src/fbdev.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/fbdev.c b/src/fbdev.c
index f25ef72..e4f66a2 100644
--- a/src/fbdev.c
+++ b/src/fbdev.c
@@ -1010,7 +1010,7 @@ FBDevScreenInit(SCREEN_INIT_ARGS_DECL)
 	fPtr->CloseScreen = pScreen->CloseScreen;
 	pScreen->CloseScreen = FBDevCloseScreen;

-#if XV
+#ifdef XV
 	{
 	    XF86VideoAdaptorPtr *ptr;

--
cgit v1.2.1