~ubuntu-branches/ubuntu/trusty/unzip/trusty

« back to all changes in this revision

Viewing changes to debian/patches/04-unzip60-alt-iconv-utf8

  • Committer: Package Import Robot
  • Author(s): Logan Rosen
  • Date: 2012-08-05 21:31:45 UTC
  • mfrom: (2.1.8 sid)
  • Revision ID: package-import@ubuntu.com-20120805213145-yjn97p3843amjk91
Tags: 6.0-7ubuntu1
* Merge from Debian unstable. Remaining change:
  - Added patch from archlinux which adds the -O option allowing a charset
  to be specified for the proper unzipping of non-latin and non-unicode
  filenames.
* Merge adds Multi-Arch: foreign. (LP: #1010450)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
From: Giovanni Scafora <giovanni.archlinux.org>
2
 
Subject: unzip files encoded with non-latin, non-unicode file names
3
 
 
4
 
diff -r e812cb68e51d unix/unix.c
5
 
--- a/unix/unix.c       Tue Jun 23 23:08:25 2009 -0500
6
 
+++ b/unix/unix.c       Thu Jun 25 00:10:29 2009 -0500
7
 
@@ -30,6 +30,9 @@
8
 
 #define UNZIP_INTERNAL
9
 
 #include "unzip.h"
10
 
 
11
 
+#include <iconv.h>
12
 
+#include <langinfo.h>
13
 
+
14
 
 #ifdef SCO_XENIX
15
 
 #  define SYSNDIR
16
 
 #else  /* SCO Unix, AIX, DNIX, TI SysV, Coherent 4.x, ... */
17
 
@@ -1874,3 +1877,90 @@
18
 
     }
19
 
 }
20
 
 #endif /* QLZIP */
21
 
+
22
 
+
23
 
+typedef struct {
24
 
+    char *local_charset;
25
 
+    char *archive_charset;
26
 
+} CHARSET_MAP;
27
 
+
28
 
+/* A mapping of local <-> archive charsets used by default to convert filenames
29
 
+ * of DOS/Windows Zip archives. Currently very basic. */
30
 
+static CHARSET_MAP dos_charset_map[] = {
31
 
+    { "ANSI_X3.4-1968", "CP850" },
32
 
+    { "ISO-8859-1", "CP850" },
33
 
+    { "CP1252", "CP850" },
34
 
+    { "UTF-8", "CP866" },
35
 
+    { "KOI8-R", "CP866" },
36
 
+    { "KOI8-U", "CP866" },
37
 
+    { "ISO-8859-5", "CP866" }
38
 
+};
39
 
+
40
 
+char OEM_CP[MAX_CP_NAME] = "";
41
 
+char ISO_CP[MAX_CP_NAME] = "";
42
 
+
43
 
+/* Try to guess the default value of OEM_CP based on the current locale.
44
 
+ * ISO_CP is left alone for now. */
45
 
+void init_conversion_charsets()
46
 
+{
47
 
+    const char *local_charset;
48
 
+    int i;
49
 
+
50
 
+    /* Make a guess only if OEM_CP not already set. */ 
51
 
+    if(*OEM_CP == '\0') {
52
 
+       local_charset = nl_langinfo(CODESET);
53
 
+       for(i = 0; i < sizeof(dos_charset_map)/sizeof(CHARSET_MAP); i++)
54
 
+               if(!strcasecmp(local_charset, dos_charset_map[i].local_charset)) {
55
 
+                       strncpy(OEM_CP, dos_charset_map[i].archive_charset,
56
 
+                                       sizeof(OEM_CP));
57
 
+                       break;
58
 
+               }
59
 
+    }
60
 
+}
61
 
+
62
 
+/* Convert a string from one encoding to the current locale using iconv().
63
 
+ * Be as non-intrusive as possible. If error is encountered during covertion
64
 
+ * just leave the string intact. */
65
 
+static void charset_to_intern(char *string, char *from_charset)
66
 
+{
67
 
+    iconv_t cd;
68
 
+    char *s,*d, *buf;
69
 
+    size_t slen, dlen, buflen;
70
 
+    const char *local_charset;
71
 
+
72
 
+    if(*from_charset == '\0')
73
 
+       return;
74
 
+
75
 
+    buf = NULL;
76
 
+    local_charset = nl_langinfo(CODESET);
77
 
+
78
 
+    if((cd = iconv_open(local_charset, from_charset)) == (iconv_t)-1)
79
 
+        return;
80
 
+
81
 
+    slen = strlen(string);
82
 
+    s = string;
83
 
+    dlen = buflen = 2*slen;
84
 
+    d = buf = malloc(buflen + 1);
85
 
+    if(!d)
86
 
+       goto cleanup;
87
 
+    bzero(buf,buflen);
88
 
+    if(iconv(cd, &s, &slen, &d, &dlen) == (size_t)-1)
89
 
+       goto cleanup;
90
 
+    strncpy(string, buf, buflen);
91
 
+    
92
 
+    cleanup:
93
 
+    free(buf);
94
 
+    iconv_close(cd);
95
 
+}
96
 
+
97
 
+/* Convert a string from OEM_CP to the current locale charset. */
98
 
+inline void oem_intern(char *string)
99
 
+{
100
 
+    charset_to_intern(string, OEM_CP);
101
 
+}
102
 
+
103
 
+/* Convert a string from ISO_CP to the current locale charset. */
104
 
+inline void iso_intern(char *string)
105
 
+{
106
 
+    charset_to_intern(string, ISO_CP);
107
 
+}
108
 
diff -r e812cb68e51d unix/unxcfg.h
109
 
--- a/unix/unxcfg.h     Tue Jun 23 23:08:25 2009 -0500
110
 
+++ b/unix/unxcfg.h     Thu Jun 25 00:10:29 2009 -0500
111
 
@@ -227,4 +227,30 @@
112
 
 /* wild_dir, dirname, wildname, matchname[], dirnamelen, have_dirname, */
113
 
 /*    and notfirstcall are used by do_wild().                          */
114
 
 
115
 
+
116
 
+#define MAX_CP_NAME 25 
117
 
+   
118
 
+#ifdef SETLOCALE
119
 
+#  undef SETLOCALE
120
 
+#endif
121
 
+#define SETLOCALE(category, locale) setlocale(category, locale)
122
 
+#include <locale.h>
123
 
+   
124
 
+#ifdef _ISO_INTERN
125
 
+#  undef _ISO_INTERN
126
 
+#endif
127
 
+#define _ISO_INTERN(str1) iso_intern(str1)
128
 
+
129
 
+#ifdef _OEM_INTERN
130
 
+#  undef _OEM_INTERN
131
 
+#endif
132
 
+#ifndef IZ_OEM2ISO_ARRAY
133
 
+#  define IZ_OEM2ISO_ARRAY
134
 
+#endif
135
 
+#define _OEM_INTERN(str1) oem_intern(str1)
136
 
+
137
 
+void iso_intern(char *);
138
 
+void oem_intern(char *);
139
 
+void init_conversion_charsets(void);
140
 
+   
141
 
 #endif /* !__unxcfg_h */
142
 
diff -r e812cb68e51d unzip.c
143
 
--- a/unzip.c   Tue Jun 23 23:08:25 2009 -0500
144
 
+++ b/unzip.c   Thu Jun 25 00:10:29 2009 -0500
145
 
@@ -327,11 +327,21 @@
146
 
   -2  just filenames but allow -h/-t/-z  -l  long Unix \"ls -l\" format\n\
147
 
                                          -v  verbose, multi-page format\n";
148
 
 
149
 
+#ifndef UNIX
150
 
 static ZCONST char Far ZipInfoUsageLine3[] = "miscellaneous options:\n\
151
 
   -h  print header line       -t  print totals for listed files or for all\n\
152
 
   -z  print zipfile comment   -T  print file times in sortable decimal format\
153
 
 \n  -C  be case-insensitive   %s\
154
 
   -x  exclude filenames that follow from listing\n";
155
 
+#else /* UNIX */
156
 
+static ZCONST char Far ZipInfoUsageLine3[] = "miscellaneous options:\n\
157
 
+  -h  print header line       -t  print totals for listed files or for all\n\
158
 
+  -z  print zipfile comment  %c-T%c print file times in sortable decimal format\
159
 
+\n %c-C%c be case-insensitive   %s\
160
 
+  -x  exclude filenames that follow from listing\n\
161
 
+  -O CHARSET  specify a character encoding for DOS, Windows and OS/2 archives\n\
162
 
+  -I CHARSET  specify a character encoding for UNIX and other archives\n";
163
 
+#endif /* !UNIX */
164
 
 #ifdef MORE
165
 
    static ZCONST char Far ZipInfoUsageLine4[] =
166
 
      "  -M  page output through built-in \"more\"\n";
167
 
@@ -665,6 +675,17 @@
168
 
   -U  use escapes for all non-ASCII Unicode  -UU ignore any Unicode fields\n\
169
 
   -C  match filenames case-insensitively     -L  make (some) names \
170
 
 lowercase\n %-42s  -V  retain VMS version numbers\n%s";
171
 
+#elif (defined UNIX)
172
 
+static ZCONST char Far UnzipUsageLine4[] = "\
173
 
+modifiers:\n\
174
 
+  -n  never overwrite existing files         -q  quiet mode (-qq => quieter)\n\
175
 
+  -o  overwrite files WITHOUT prompting      -a  auto-convert any text files\n\
176
 
+  -j  junk paths (do not make directories)   -aa treat ALL files as text\n\
177
 
+  -U  use escapes for all non-ASCII Unicode  -UU ignore any Unicode fields\n\
178
 
+  -C  match filenames case-insensitively     -L  make (some) names \
179
 
+lowercase\n %-42s  -V  retain VMS version numbers\n%s\
180
 
+  -O CHARSET  specify a character encoding for DOS, Windows and OS/2 archives\n\
181
 
+  -I CHARSET  specify a character encoding for UNIX and other archives\n\n";
182
 
 #else /* !VMS */
183
 
 static ZCONST char Far UnzipUsageLine4[] = "\
184
 
 modifiers:\n\
185
 
@@ -803,6 +824,10 @@
186
 
 #endif /* UNICODE_SUPPORT */
187
 
 
188
 
 
189
 
+#ifdef UNIX
190
 
+    init_conversion_charsets();
191
 
+#endif
192
 
+
193
 
 #if (defined(__IBMC__) && defined(__DEBUG_ALLOC__))
194
 
     extern void DebugMalloc(void);
195
 
 
196
 
@@ -1336,6 +1361,11 @@
197
 
     argc = *pargc;
198
 
     argv = *pargv;
199
 
 
200
 
+#ifdef UNIX
201
 
+    extern char OEM_CP[MAX_CP_NAME];
202
 
+    extern char ISO_CP[MAX_CP_NAME];
203
 
+#endif
204
 
+    
205
 
     while (++argv, (--argc > 0 && *argv != NULL && **argv == '-')) {
206
 
         s = *argv + 1;
207
 
         while ((c = *s++) != 0) {    /* "!= 0":  prevent Turbo C warning */
208
 
@@ -1517,6 +1547,35 @@
209
 
                     }
210
 
                     break;
211
 
 #endif  /* MACOS */
212
 
+#ifdef UNIX
213
 
+                       case ('I'):
214
 
+                    if (negative) {
215
 
+                        Info(slide, 0x401, ((char *)slide,
216
 
+                          "error:  encodings can't be negated"));
217
 
+                        return(PK_PARAM);
218
 
+                               } else {
219
 
+                                       if(*s) { /* Handle the -Icharset case */
220
 
+                                               /* Assume that charsets can't start with a dash to spot arguments misuse */
221
 
+                                               if(*s == '-') { 
222
 
+                               Info(slide, 0x401, ((char *)slide,
223
 
+                                         "error:  a valid character encoding should follow the -I argument"));
224
 
+                               return(PK_PARAM); 
225
 
+                                               }
226
 
+                                               strncpy(ISO_CP, s, sizeof(ISO_CP));
227
 
+                                       } else { /* -I charset */
228
 
+                                               ++argv;
229
 
+                                               if(!(--argc > 0 && *argv != NULL && **argv != '-')) {
230
 
+                               Info(slide, 0x401, ((char *)slide,
231
 
+                                         "error:  a valid character encoding should follow the -I argument"));
232
 
+                               return(PK_PARAM); 
233
 
+                                               }
234
 
+                                               s = *argv;
235
 
+                                               strncpy(ISO_CP, s, sizeof(ISO_CP));
236
 
+                                       }
237
 
+                                       while(*(++s)); /* No params straight after charset name */
238
 
+                               }
239
 
+                               break;
240
 
+#endif /* ?UNIX */
241
 
                 case ('j'):    /* junk pathnames/directory structure */
242
 
                     if (negative)
243
 
                         uO.jflag = FALSE, negative = 0;
244
 
@@ -1592,6 +1651,35 @@
245
 
                     } else
246
 
                         ++uO.overwrite_all;
247
 
                     break;
248
 
+#ifdef UNIX
249
 
+                       case ('O'):
250
 
+                    if (negative) {
251
 
+                        Info(slide, 0x401, ((char *)slide,
252
 
+                          "error:  encodings can't be negated"));
253
 
+                        return(PK_PARAM);
254
 
+                               } else {
255
 
+                                       if(*s) { /* Handle the -Ocharset case */
256
 
+                                               /* Assume that charsets can't start with a dash to spot arguments misuse */
257
 
+                                               if(*s == '-') { 
258
 
+                               Info(slide, 0x401, ((char *)slide,
259
 
+                                         "error:  a valid character encoding should follow the -I argument"));
260
 
+                               return(PK_PARAM); 
261
 
+                                               }
262
 
+                                               strncpy(OEM_CP, s, sizeof(OEM_CP));
263
 
+                                       } else { /* -O charset */
264
 
+                                               ++argv;
265
 
+                                               if(!(--argc > 0 && *argv != NULL && **argv != '-')) {
266
 
+                               Info(slide, 0x401, ((char *)slide,
267
 
+                                         "error:  a valid character encoding should follow the -O argument"));
268
 
+                               return(PK_PARAM); 
269
 
+                                               }
270
 
+                                               s = *argv;
271
 
+                                               strncpy(OEM_CP, s, sizeof(OEM_CP));
272
 
+                                       }
273
 
+                                       while(*(++s)); /* No params straight after charset name */
274
 
+                               }
275
 
+                               break;
276
 
+#endif /* ?UNIX */
277
 
                 case ('p'):    /* pipes:  extract to stdout, no messages */
278
 
                     if (negative) {
279
 
                         uO.cflag = FALSE;
280
 
diff -r e812cb68e51d unzpriv.h
281
 
--- a/unzpriv.h Tue Jun 23 23:08:25 2009 -0500
282
 
+++ b/unzpriv.h Thu Jun 25 00:10:29 2009 -0500
283
 
@@ -3008,7 +3008,7 @@
284
 
          !(((islochdr) || (isuxatt)) && \
285
 
            ((hostver) == 25 || (hostver) == 26 || (hostver) == 40))) || \
286
 
         (hostnum) == FS_HPFS_ || \
287
 
-        ((hostnum) == FS_NTFS_ && (hostver) == 50)) { \
288
 
+        ((hostnum) == FS_NTFS_ /* && (hostver) == 50 */ )) { \
289
 
         _OEM_INTERN((string)); \
290
 
     } else { \
291
 
         _ISO_INTERN((string)); \
292
 
diff -r e812cb68e51d zipinfo.c
293
 
--- a/zipinfo.c Tue Jun 23 23:08:25 2009 -0500
294
 
+++ b/zipinfo.c Thu Jun 25 00:10:29 2009 -0500
295
 
@@ -457,6 +457,10 @@
296
 
     int    tflag_slm=TRUE, tflag_2v=FALSE;
297
 
     int    explicit_h=FALSE, explicit_t=FALSE;
298
 
 
299
 
+#ifdef UNIX
300
 
+    extern char OEM_CP[MAX_CP_NAME];
301
 
+    extern char ISO_CP[MAX_CP_NAME];
302
 
+#endif
303
 
 
304
 
 #ifdef MACOS
305
 
     uO.lflag = LFLAG;         /* reset default on each call */
306
 
@@ -501,6 +505,35 @@
307
 
                             uO.lflag = 0;
308
 
                     }
309
 
                     break;
310
 
+#ifdef UNIX
311
 
+                       case ('I'):
312
 
+                    if (negative) {
313
 
+                        Info(slide, 0x401, ((char *)slide,
314
 
+                          "error:  encodings can't be negated"));
315
 
+                        return(PK_PARAM);
316
 
+                               } else {
317
 
+                                       if(*s) { /* Handle the -Icharset case */
318
 
+                                               /* Assume that charsets can't start with a dash to spot arguments misuse */
319
 
+                                               if(*s == '-') { 
320
 
+                               Info(slide, 0x401, ((char *)slide,
321
 
+                                         "error:  a valid character encoding should follow the -I argument"));
322
 
+                               return(PK_PARAM); 
323
 
+                                               }
324
 
+                                               strncpy(ISO_CP, s, sizeof(ISO_CP));
325
 
+                                       } else { /* -I charset */
326
 
+                                               ++argv;
327
 
+                                               if(!(--argc > 0 && *argv != NULL && **argv != '-')) {
328
 
+                               Info(slide, 0x401, ((char *)slide,
329
 
+                                         "error:  a valid character encoding should follow the -I argument"));
330
 
+                               return(PK_PARAM); 
331
 
+                                               }
332
 
+                                               s = *argv;
333
 
+                                               strncpy(ISO_CP, s, sizeof(ISO_CP));
334
 
+                                       }
335
 
+                                       while(*(++s)); /* No params straight after charset name */
336
 
+                               }
337
 
+                               break;
338
 
+#endif /* ?UNIX */
339
 
                 case 'l':      /* longer form of "ls -l" type listing */
340
 
                     if (negative)
341
 
                         uO.lflag = -2, negative = 0;
342
 
@@ -521,6 +554,35 @@
343
 
                         G.M_flag = TRUE;
344
 
                     break;
345
 
 #endif
346
 
+#ifdef UNIX
347
 
+                       case ('O'):
348
 
+                    if (negative) {
349
 
+                        Info(slide, 0x401, ((char *)slide,
350
 
+                          "error:  encodings can't be negated"));
351
 
+                        return(PK_PARAM);
352
 
+                               } else {
353
 
+                                       if(*s) { /* Handle the -Ocharset case */
354
 
+                                               /* Assume that charsets can't start with a dash to spot arguments misuse */
355
 
+                                               if(*s == '-') { 
356
 
+                               Info(slide, 0x401, ((char *)slide,
357
 
+                                         "error:  a valid character encoding should follow the -I argument"));
358
 
+                               return(PK_PARAM); 
359
 
+                                               }
360
 
+                                               strncpy(OEM_CP, s, sizeof(OEM_CP));
361
 
+                                       } else { /* -O charset */
362
 
+                                               ++argv;
363
 
+                                               if(!(--argc > 0 && *argv != NULL && **argv != '-')) {
364
 
+                               Info(slide, 0x401, ((char *)slide,
365
 
+                                         "error:  a valid character encoding should follow the -O argument"));
366
 
+                               return(PK_PARAM); 
367
 
+                                               }
368
 
+                                               s = *argv;
369
 
+                                               strncpy(OEM_CP, s, sizeof(OEM_CP));
370
 
+                                       }
371
 
+                                       while(*(++s)); /* No params straight after charset name */
372
 
+                               }
373
 
+                               break;
374
 
+#endif /* ?UNIX */
375
 
                 case 's':      /* default:  shorter "ls -l" type listing */
376
 
                     if (negative)
377
 
                         uO.lflag = -2, negative = 0;