galeb-mkfiles

Извори пакета за Галеб
Дневник | Датотеке | Референце | ПРОЧИТАЈМЕ | ЛИЦЕНЦА

0003-unzip-6.0-alt-iconv-utf8-print.patch (12880B)


      1 From ca0212ba19b64488b9e8459a762c11ecd6e7d0bd Mon Sep 17 00:00:00 2001
      2 From: Petr Stodulka <pstodulk@redhat.com>
      3 Date: Tue, 24 Nov 2015 17:56:11 +0100
      4 Subject: [PATCH] print correctly non-ascii filenames
      5 
      6 ---
      7  extract.c | 289 ++++++++++++++++++++++++++++++++++++++++++++++++--------------
      8  unzpriv.h |   7 ++
      9  2 files changed, 233 insertions(+), 63 deletions(-)
     10 
     11 diff --git a/extract.c b/extract.c
     12 index 0ee4e93..741b7e0 100644
     13 --- a/extract.c
     14 +++ b/extract.c
     15 @@ -2648,8 +2648,21 @@ static void set_deferred_symlink(__G__ slnk_entry)
     16  } /* end function set_deferred_symlink() */
     17  #endif /* SYMLINKS */
     18  
     19 +/*
     20 + * If Unicode is supported, assume we have what we need to do this
     21 + * check using wide characters, avoiding MBCS issues.
     22 + */
     23  
     24 -
     25 +#ifndef UZ_FNFILTER_REPLACECHAR
     26 +        /* A convenient choice for the replacement of unprintable char codes is
     27 +         * the "single char wildcard", as this character is quite unlikely to
     28 +         * appear in filenames by itself.  The following default definition
     29 +         * sets the replacement char to a question mark as the most common
     30 +         * "single char wildcard"; this setting should be overridden in the
     31 +         * appropiate system-specific configuration header when needed.
     32 +         */
     33 +# define UZ_FNFILTER_REPLACECHAR      '?'
     34 +#endif
     35  
     36  /*************************/
     37  /*  Function fnfilter()  */        /* here instead of in list.c for SFX */
     38 @@ -2661,48 +2674,168 @@ char *fnfilter(raw, space, size)   /* convert name to safely printable form */
     39      extent size;
     40  {
     41  #ifndef NATIVE   /* ASCII:  filter ANSI escape codes, etc. */
     42 -    ZCONST uch *r=(ZCONST uch *)raw;
     43 +    ZCONST uch *r; // =(ZCONST uch *)raw;
     44      uch *s=space;
     45      uch *slim=NULL;
     46      uch *se=NULL;
     47      int have_overflow = FALSE;
     48  
     49 -    if (size > 0) {
     50 -        slim = space + size
     51 -#ifdef _MBCS
     52 -                     - (MB_CUR_MAX - 1)
     53 -#endif
     54 -                     - 4;
     55 +# if defined( UNICODE_SUPPORT) && defined( _MBCS)
     56 +/* If Unicode support is enabled, and we have multi-byte characters,
     57 + * then do the isprint() checks by first converting to wide characters
     58 + * and checking those.  This avoids our having to parse multi-byte
     59 + * characters for ourselves.  After the wide-char replacements have been
     60 + * made, the wide string is converted back to the local character set.
     61 + */
     62 +    wchar_t *wstring;    /* wchar_t version of raw */
     63 +    size_t wslen;        /* length of wstring */
     64 +    wchar_t *wostring;   /* wchar_t version of output string */
     65 +    size_t woslen;       /* length of wostring */
     66 +    char *newraw;        /* new raw */
     67 +
     68 +    /* 2012-11-06 SMS.
     69 +     * Changed to check the value returned by mbstowcs(), and bypass the
     70 +     * Unicode processing if it fails.  This seems to fix a problem
     71 +     * reported in the SourceForge forum, but it's not clear that we
     72 +     * should be doing any Unicode processing without some evidence that
     73 +     * the name actually is Unicode.  (Check bit 11 in the flags before
     74 +     * coming here?)
     75 +     * http://sourceforge.net/p/infozip/bugs/40/
     76 +     */
     77 +
     78 +    if (MB_CUR_MAX <= 1)
     79 +    {
     80 +        /* There's no point to converting multi-byte chars if there are
     81 +         * no multi-byte chars.
     82 +         */
     83 +        wslen = (size_t)-1;
     84      }
     85 -    while (*r) {
     86 -        if (size > 0 && s >= slim && se == NULL) {
     87 -            se = s;
     88 +    else
     89 +    {
     90 +        /* Get Unicode wide character count (for storage allocation). */
     91 +        wslen = mbstowcs( NULL, raw, 0);
     92 +    }
     93 +
     94 +    if (wslen != (size_t)-1)
     95 +    {
     96 +        /* Apparently valid Unicode.  Allocate wide-char storage. */
     97 +        wstring = (wchar_t *)malloc((wslen + 1) * sizeof(wchar_t));
     98 +        if (wstring == NULL) {
     99 +            strcpy( (char *)space, raw);
    100 +            return (char *)space;
    101          }
    102 -#ifdef QDOS
    103 -        if (qlflag & 2) {
    104 -            if (*r == '/' || *r == '.') {
    105 +        wostring = (wchar_t *)malloc(2 * (wslen + 1) * sizeof(wchar_t));
    106 +        if (wostring == NULL) {
    107 +            free(wstring);
    108 +            strcpy( (char *)space, raw);
    109 +            return (char *)space;
    110 +        }
    111 +
    112 +        /* Convert the multi-byte Unicode to wide chars. */
    113 +        wslen = mbstowcs(wstring, raw, wslen + 1);
    114 +
    115 +        /* Filter the wide-character string. */
    116 +        fnfilterw( wstring, wostring, (2 * (wslen + 1) * sizeof(wchar_t)));
    117 +
    118 +        /* Convert filtered wide chars back to multi-byte. */
    119 +        woslen = wcstombs( NULL, wostring, 0);
    120 +        if ((newraw = malloc(woslen + 1)) == NULL) {
    121 +            free(wstring);
    122 +            free(wostring);
    123 +            strcpy( (char *)space, raw);
    124 +            return (char *)space;
    125 +        }
    126 +        woslen = wcstombs( newraw, wostring, (woslen * MB_CUR_MAX) + 1);
    127 +
    128 +        if (size > 0) {
    129 +            slim = space + size - 4;
    130 +        }
    131 +        r = (ZCONST uch *)newraw;
    132 +        while (*r) {
    133 +            if (size > 0 && s >= slim && se == NULL) {
    134 +                se = s;
    135 +            }
    136 +#  ifdef QDOS
    137 +            if (qlflag & 2) {
    138 +                if (*r == '/' || *r == '.') {
    139 +                    if (se != NULL && (s > (space + (size-3)))) {
    140 +                        have_overflow = TRUE;
    141 +                        break;
    142 +                    }
    143 +                    ++r;
    144 +                    *s++ = '_';
    145 +                    continue;
    146 +                }
    147 +            } else
    148 +#  endif
    149 +            {
    150                  if (se != NULL && (s > (space + (size-3)))) {
    151                      have_overflow = TRUE;
    152                      break;
    153                  }
    154 -                ++r;
    155 -                *s++ = '_';
    156 -                continue;
    157 +                *s++ = *r++;
    158              }
    159 -        } else
    160 +        }
    161 +        if (have_overflow) {
    162 +            strcpy((char *)se, "...");
    163 +        } else {
    164 +            *s = '\0';
    165 +        }
    166 +
    167 +        free(wstring);
    168 +        free(wostring);
    169 +        free(newraw);
    170 +    }
    171 +    else
    172 +# endif /* defined( UNICODE_SUPPORT) && defined( _MBCS) */
    173 +    {
    174 +        /* No Unicode support, or apparently invalid Unicode. */
    175 +        r = (ZCONST uch *)raw;
    176 +
    177 +        if (size > 0) {
    178 +            slim = space + size
    179 +#ifdef _MBCS
    180 +                         - (MB_CUR_MAX - 1)
    181 +#endif
    182 +                         - 4;
    183 +        }
    184 +        while (*r) {
    185 +            if (size > 0 && s >= slim && se == NULL) {
    186 +                se = s;
    187 +            }
    188 +#ifdef QDOS
    189 +            if (qlflag & 2) {
    190 +                if (*r == '/' || *r == '.') {
    191 +                    if (se != NULL && (s > (space + (size-3)))) {
    192 +                        have_overflow = TRUE;
    193 +                        break;
    194 +                    }
    195 +                    ++r;
    196 +                    *s++ = '_';
    197 +                    continue;
    198 +                }
    199 +            } else
    200  #endif
    201  #ifdef HAVE_WORKING_ISPRINT
    202 -# ifndef UZ_FNFILTER_REPLACECHAR
    203 -    /* A convenient choice for the replacement of unprintable char codes is
    204 -     * the "single char wildcard", as this character is quite unlikely to
    205 -     * appear in filenames by itself.  The following default definition
    206 -     * sets the replacement char to a question mark as the most common
    207 -     * "single char wildcard"; this setting should be overridden in the
    208 -     * appropiate system-specific configuration header when needed.
    209 -     */
    210 -#   define UZ_FNFILTER_REPLACECHAR      '?'
    211 -# endif
    212 -        if (!isprint(*r)) {
    213 +            if (!isprint(*r)) {
    214 +                if (*r < 32) {
    215 +                    /* ASCII control codes are escaped as "^{letter}". */
    216 +                    if (se != NULL && (s > (space + (size-4)))) {
    217 +                        have_overflow = TRUE;
    218 +                        break;
    219 +                    }
    220 +                    *s++ = '^', *s++ = (uch)(64 + *r++);
    221 +                } else {
    222 +                    /* Other unprintable codes are replaced by the
    223 +                     * placeholder character. */
    224 +                    if (se != NULL && (s > (space + (size-3)))) {
    225 +                        have_overflow = TRUE;
    226 +                        break;
    227 +                    }
    228 +                    *s++ = UZ_FNFILTER_REPLACECHAR;
    229 +                    INCSTR(r);
    230 +                }
    231 +#else /* !HAVE_WORKING_ISPRINT */
    232              if (*r < 32) {
    233                  /* ASCII control codes are escaped as "^{letter}". */
    234                  if (se != NULL && (s > (space + (size-4)))) {
    235 @@ -2710,47 +2843,30 @@ char *fnfilter(raw, space, size)   /* convert name to safely printable form */
    236                      break;
    237                  }
    238                  *s++ = '^', *s++ = (uch)(64 + *r++);
    239 +#endif /* ?HAVE_WORKING_ISPRINT */
    240              } else {
    241 -                /* Other unprintable codes are replaced by the
    242 -                 * placeholder character. */
    243 +#ifdef _MBCS
    244 +                unsigned i = CLEN(r);
    245 +                if (se != NULL && (s > (space + (size-i-2)))) {
    246 +                    have_overflow = TRUE;
    247 +                    break;
    248 +                }
    249 +                for (; i > 0; i--)
    250 +                    *s++ = *r++;
    251 +#else
    252                  if (se != NULL && (s > (space + (size-3)))) {
    253                      have_overflow = TRUE;
    254                      break;
    255                  }
    256 -                *s++ = UZ_FNFILTER_REPLACECHAR;
    257 -                INCSTR(r);
    258 -            }
    259 -#else /* !HAVE_WORKING_ISPRINT */
    260 -        if (*r < 32) {
    261 -            /* ASCII control codes are escaped as "^{letter}". */
    262 -            if (se != NULL && (s > (space + (size-4)))) {
    263 -                have_overflow = TRUE;
    264 -                break;
    265 -            }
    266 -            *s++ = '^', *s++ = (uch)(64 + *r++);
    267 -#endif /* ?HAVE_WORKING_ISPRINT */
    268 -        } else {
    269 -#ifdef _MBCS
    270 -            unsigned i = CLEN(r);
    271 -            if (se != NULL && (s > (space + (size-i-2)))) {
    272 -                have_overflow = TRUE;
    273 -                break;
    274 -            }
    275 -            for (; i > 0; i--)
    276                  *s++ = *r++;
    277 -#else
    278 -            if (se != NULL && (s > (space + (size-3)))) {
    279 -                have_overflow = TRUE;
    280 -                break;
    281 -            }
    282 -            *s++ = *r++;
    283  #endif
    284 -         }
    285 -    }
    286 -    if (have_overflow) {
    287 -        strcpy((char *)se, "...");
    288 -    } else {
    289 -        *s = '\0';
    290 +             }
    291 +        }
    292 +        if (have_overflow) {
    293 +            strcpy((char *)se, "...");
    294 +        } else {
    295 +            *s = '\0';
    296 +        }
    297      }
    298  
    299  #ifdef WINDLL
    300 @@ -2772,6 +2888,53 @@ char *fnfilter(raw, space, size)   /* convert name to safely printable form */
    301  } /* end function fnfilter() */
    302  
    303  
    304 +#if defined( UNICODE_SUPPORT) && defined( _MBCS)
    305 +
    306 +/****************************/
    307 +/*  Function fnfilter[w]()  */  /* (Here instead of in list.c for SFX.) */
    308 +/****************************/
    309 +
    310 +/* fnfilterw() - Convert wide name to safely printable form. */
    311 +
    312 +/* fnfilterw() - Convert wide-character name to safely printable form. */
    313 +
    314 +wchar_t *fnfilterw( src, dst, siz)
    315 +    ZCONST wchar_t *src;        /* Pointer to source char (string). */
    316 +    wchar_t *dst;               /* Pointer to destination char (string). */
    317 +    extent siz;                 /* Not used (!). */
    318 +{
    319 +    wchar_t *dsx = dst;
    320 +
    321 +    /* Filter the wide chars. */
    322 +    while (*src)
    323 +    {
    324 +        if (iswprint( *src))
    325 +        {
    326 +            /* Printable code.  Copy it. */
    327 +            *dst++ = *src;
    328 +        }
    329 +        else
    330 +        {
    331 +            /* Unprintable code.  Substitute something printable for it. */
    332 +            if (*src < 32)
    333 +            {
    334 +                /* Replace ASCII control code with "^{letter}". */
    335 +                *dst++ = (wchar_t)'^';
    336 +                *dst++ = (wchar_t)(64 + *src);
    337 +            }
    338 +            else
    339 +            {
    340 +                /* Replace other unprintable code with the placeholder. */
    341 +                *dst++ = (wchar_t)UZ_FNFILTER_REPLACECHAR;
    342 +            }
    343 +        }
    344 +        src++;
    345 +    }
    346 +    *dst = (wchar_t)0;  /* NUL-terminate the destination string. */
    347 +    return dsx;
    348 +} /* fnfilterw(). */
    349 +
    350 +#endif /* defined( UNICODE_SUPPORT) && defined( _MBCS) */
    351  
    352  
    353  #ifdef SET_DIR_ATTRIB
    354 diff --git a/unzpriv.h b/unzpriv.h
    355 index 22d3923..e48a652 100644
    356 --- a/unzpriv.h
    357 +++ b/unzpriv.h
    358 @@ -1212,6 +1212,7 @@
    359  # ifdef UNICODE_WCHAR
    360  #  if !(defined(_WIN32_WCE) || defined(POCKET_UNZIP))
    361  #   include <wchar.h>
    362 +#   include <wctype.h>
    363  #  endif
    364  # endif
    365  # ifndef _MBCS  /* no need to include <locale.h> twice, see below */
    366 @@ -2410,6 +2411,12 @@ int    memflush                  OF((__GPRO__ ZCONST uch *rawbuf, ulg size));
    367  char  *fnfilter                  OF((ZCONST char *raw, uch *space,
    368                                       extent size));
    369  
    370 +# if defined( UNICODE_SUPPORT) && defined( _MBCS)
    371 +wchar_t *fnfilterw               OF((ZCONST wchar_t *src, wchar_t *dst,
    372 +                                     extent siz));
    373 +#endif
    374 +
    375 +
    376  /*---------------------------------------------------------------------------
    377      Decompression functions:
    378    ---------------------------------------------------------------------------*/
    379 -- 
    380 2.4.3
    381