~ubuntu-branches/ubuntu/quantal/unzip/quantal-proposed

« back to all changes in this revision

Viewing changes to debian/patches/05-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;