]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - libarchive/archive_read_support_format_zip.c
Update libarchive's vendor dist to latest changes in release branch.
[FreeBSD/FreeBSD.git] / libarchive / archive_read_support_format_zip.c
1 /*-
2  * Copyright (c) 2004 Tim Kientzle
3  * Copyright (c) 2011-2012 Michihiro NAKAJIMA
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18  * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26
27 #include "archive_platform.h"
28 __FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_zip.c 201102 2009-12-28 03:11:36Z kientzle $");
29
30 #ifdef HAVE_ERRNO_H
31 #include <errno.h>
32 #endif
33 #ifdef HAVE_STDLIB_H
34 #include <stdlib.h>
35 #endif
36 #ifdef HAVE_ZLIB_H
37 #include <zlib.h>
38 #endif
39
40 #include "archive.h"
41 #include "archive_entry.h"
42 #include "archive_entry_locale.h"
43 #include "archive_private.h"
44 #include "archive_read_private.h"
45 #include "archive_endian.h"
46
47 #ifndef HAVE_ZLIB_H
48 #include "archive_crc32.h"
49 #endif
50
51 struct zip_entry {
52         int64_t                 local_header_offset;
53         int64_t                 compressed_size;
54         int64_t                 uncompressed_size;
55         int64_t                 gid;
56         int64_t                 uid;
57         struct archive_entry    *entry;
58         time_t                  mtime;
59         time_t                  atime;
60         time_t                  ctime;
61         uint32_t                crc32;
62         uint16_t                mode;
63         uint16_t                flags;
64         char                    compression;
65         char                    system;
66 };
67
68 struct zip {
69         /* Structural information about the archive. */
70         int64_t                 central_directory_offset;
71         size_t                  central_directory_size;
72         size_t                  central_directory_entries;
73         char                    have_central_directory;
74
75         /* List of entries (seekable Zip only) */
76         size_t                  entries_remaining;
77         struct zip_entry        *zip_entries;
78         struct zip_entry        *entry;
79
80         size_t                  unconsumed;
81
82         /* entry_bytes_remaining is the number of bytes we expect. */
83         int64_t                 entry_bytes_remaining;
84
85         /* These count the number of bytes actually read for the entry. */
86         int64_t                 entry_compressed_bytes_read;
87         int64_t                 entry_uncompressed_bytes_read;
88
89         /* Running CRC32 of the decompressed data */
90         unsigned long           entry_crc32;
91
92         /* Flags to mark progress of decompression. */
93         char                    decompress_init;
94         char                    end_of_entry;
95
96         ssize_t                 filename_length;
97         ssize_t                 extra_length;
98
99         unsigned char           *uncompressed_buffer;
100         size_t                  uncompressed_buffer_size;
101 #ifdef HAVE_ZLIB_H
102         z_stream                stream;
103         char                    stream_valid;
104 #endif
105
106         struct archive_string   extra;
107         struct archive_string_conv *sconv;
108         struct archive_string_conv *sconv_default;
109         struct archive_string_conv *sconv_utf8;
110         int                     init_default_conversion;
111         char    format_name[64];
112 };
113
114 #define ZIP_LENGTH_AT_END       8
115 #define ZIP_ENCRYPTED           (1<<0)  
116 #define ZIP_STRONG_ENCRYPTED    (1<<6)  
117 #define ZIP_UTF8_NAME           (1<<11) 
118
119 static int      archive_read_format_zip_streamable_bid(struct archive_read *, int);
120 static int      archive_read_format_zip_seekable_bid(struct archive_read *, int);
121 static int      archive_read_format_zip_options(struct archive_read *,
122                     const char *, const char *);
123 static int      archive_read_format_zip_cleanup(struct archive_read *);
124 static int      archive_read_format_zip_read_data(struct archive_read *,
125                     const void **, size_t *, int64_t *);
126 static int      archive_read_format_zip_read_data_skip(struct archive_read *a);
127 static int      archive_read_format_zip_seekable_read_header(struct archive_read *,
128                     struct archive_entry *);
129 static int      archive_read_format_zip_streamable_read_header(struct archive_read *,
130                     struct archive_entry *);
131 #ifdef HAVE_ZLIB_H
132 static int      zip_read_data_deflate(struct archive_read *a, const void **buff,
133                     size_t *size, int64_t *offset);
134 #endif
135 static int      zip_read_data_none(struct archive_read *a, const void **buff,
136                     size_t *size, int64_t *offset);
137 static int      zip_read_local_file_header(struct archive_read *a,
138     struct archive_entry *entry, struct zip *);
139 static time_t   zip_time(const char *);
140 static const char *compression_name(int compression);
141 static void process_extra(const char *, size_t, struct zip_entry *);
142
143 int     archive_read_support_format_zip_streamable(struct archive *);
144 int     archive_read_support_format_zip_seekable(struct archive *);
145
146 int
147 archive_read_support_format_zip_streamable(struct archive *_a)
148 {
149         struct archive_read *a = (struct archive_read *)_a;
150         struct zip *zip;
151         int r;
152
153         archive_check_magic(_a, ARCHIVE_READ_MAGIC,
154             ARCHIVE_STATE_NEW, "archive_read_support_format_zip");
155
156         zip = (struct zip *)malloc(sizeof(*zip));
157         if (zip == NULL) {
158                 archive_set_error(&a->archive, ENOMEM,
159                     "Can't allocate zip data");
160                 return (ARCHIVE_FATAL);
161         }
162         memset(zip, 0, sizeof(*zip));
163
164         r = __archive_read_register_format(a,
165             zip,
166             "zip",
167             archive_read_format_zip_streamable_bid,
168             archive_read_format_zip_options,
169             archive_read_format_zip_streamable_read_header,
170             archive_read_format_zip_read_data,
171             archive_read_format_zip_read_data_skip,
172             archive_read_format_zip_cleanup);
173
174         if (r != ARCHIVE_OK)
175                 free(zip);
176         return (ARCHIVE_OK);
177 }
178
179 int
180 archive_read_support_format_zip_seekable(struct archive *_a)
181 {
182         struct archive_read *a = (struct archive_read *)_a;
183         struct zip *zip;
184         int r;
185
186         archive_check_magic(_a, ARCHIVE_READ_MAGIC,
187             ARCHIVE_STATE_NEW, "archive_read_support_format_zip_seekable");
188
189         zip = (struct zip *)malloc(sizeof(*zip));
190         if (zip == NULL) {
191                 archive_set_error(&a->archive, ENOMEM,
192                     "Can't allocate zip data");
193                 return (ARCHIVE_FATAL);
194         }
195         memset(zip, 0, sizeof(*zip));
196
197         r = __archive_read_register_format(a,
198             zip,
199             "zip",
200             archive_read_format_zip_seekable_bid,
201             archive_read_format_zip_options,
202             archive_read_format_zip_seekable_read_header,
203             archive_read_format_zip_read_data,
204             archive_read_format_zip_read_data_skip,
205             archive_read_format_zip_cleanup);
206
207         if (r != ARCHIVE_OK)
208                 free(zip);
209         return (ARCHIVE_OK);
210 }
211
212 int
213 archive_read_support_format_zip(struct archive *a)
214 {
215         int r;
216         r = archive_read_support_format_zip_streamable(a);
217         if (r != ARCHIVE_OK)
218                 return r;
219         return (archive_read_support_format_zip_seekable(a));
220 }
221
222 /*
223  * TODO: This is a performance sink because it forces the read core to
224  * drop buffered data from the start of file, which will then have to
225  * be re-read again if this bidder loses.
226  *
227  * We workaround this a little by passing in the best bid so far so
228  * that later bidders can do nothing if they know they'll never
229  * outbid.  But we can certainly do better...
230  */
231 static int
232 archive_read_format_zip_seekable_bid(struct archive_read *a, int best_bid)
233 {
234         struct zip *zip = (struct zip *)a->format->data;
235         int64_t filesize;
236         const char *p;
237
238         /* If someone has already bid more than 32, then avoid
239            trashing the look-ahead buffers with a seek. */
240         if (best_bid > 32)
241                 return (-1);
242
243         filesize = __archive_read_seek(a, -22, SEEK_END);
244         /* If we can't seek, then we can't bid. */
245         if (filesize <= 0)
246                 return 0;
247
248         /* TODO: More robust search for end of central directory record. */
249         if ((p = __archive_read_ahead(a, 22, NULL)) == NULL)
250                 return 0;
251         /* First four bytes are signature for end of central directory
252            record.  Four zero bytes ensure this isn't a multi-volume
253            Zip file (which we don't yet support). */
254         if (memcmp(p, "PK\005\006\000\000\000\000", 8) != 0)
255                 return 0;
256
257         /* Since we've already done the hard work of finding the
258            end of central directory record, let's save the important
259            information. */
260         zip->central_directory_entries = archive_le16dec(p + 10);
261         zip->central_directory_size = archive_le32dec(p + 12);
262         zip->central_directory_offset = archive_le32dec(p + 16);
263
264         /* Just one volume, so central dir must all be on this volume. */
265         if (zip->central_directory_entries != archive_le16dec(p + 8))
266                 return 0;
267         /* Central directory can't extend beyond end of this file. */
268         if (zip->central_directory_offset + (int64_t)zip->central_directory_size > filesize)
269                 return 0;
270
271         /* This is just a tiny bit higher than the maximum returned by
272            the streaming Zip bidder.  This ensures that the more accurate
273            seeking Zip parser wins whenever seek is available. */
274         return 32;
275 }
276
277 static int
278 slurp_central_directory(struct archive_read *a, struct zip *zip)
279 {
280         unsigned i;
281
282         __archive_read_seek(a, zip->central_directory_offset, SEEK_SET);
283
284         zip->zip_entries = calloc(zip->central_directory_entries, sizeof(struct zip_entry));
285         for (i = 0; i < zip->central_directory_entries; ++i) {
286                 struct zip_entry *zip_entry = &zip->zip_entries[i];
287                 size_t filename_length, extra_length, comment_length;
288                 uint32_t external_attributes;
289                 const char *p;
290
291                 if ((p = __archive_read_ahead(a, 46, NULL)) == NULL)
292                         return ARCHIVE_FATAL;
293                 if (memcmp(p, "PK\001\002", 4) != 0) {
294                         archive_set_error(&a->archive,
295                             -1, "Invalid central directory signature");
296                         return ARCHIVE_FATAL;
297                 }
298                 zip->have_central_directory = 1;
299                 /* version = p[4]; */
300                 zip_entry->system = p[5];
301                 /* version_required = archive_le16dec(p + 6); */
302                 zip_entry->flags = archive_le16dec(p + 8);
303                 zip_entry->compression = archive_le16dec(p + 10);
304                 zip_entry->mtime = zip_time(p + 12);
305                 zip_entry->crc32 = archive_le32dec(p + 16);
306                 zip_entry->compressed_size = archive_le32dec(p + 20);
307                 zip_entry->uncompressed_size = archive_le32dec(p + 24);
308                 filename_length = archive_le16dec(p + 28);
309                 extra_length = archive_le16dec(p + 30);
310                 comment_length = archive_le16dec(p + 32);
311                 /* disk_start = archive_le16dec(p + 34); */ /* Better be zero. */
312                 /* internal_attributes = archive_le16dec(p + 36); */ /* text bit */
313                 external_attributes = archive_le32dec(p + 38);
314                 zip_entry->local_header_offset = archive_le32dec(p + 42);
315
316                 /* If we can't guess the mode, leave it zero here;
317                    when we read the local file header we might get
318                    more information. */
319                 zip_entry->mode = 0;
320                 if (zip_entry->system == 3) {
321                         zip_entry->mode = external_attributes >> 16;
322                 }
323
324                 /* We don't read the filename until we get to the
325                    local file header.  Reading it here would speed up
326                    table-of-contents operations (removing the need to
327                    find and read local file header to get the
328                    filename) at the cost of requiring a lot of extra
329                    space. */
330                 /* We don't read the extra block here.  We assume it
331                    will be duplicated at the local file header. */
332                 __archive_read_consume(a,
333                     46 + filename_length + extra_length + comment_length);
334         }
335
336         /* TODO: Sort zip entries by file offset so that we
337            can optimize get_next_header() to use skip instead of
338            seek. */
339
340         return ARCHIVE_OK;
341 }
342
343 static int
344 archive_read_format_zip_seekable_read_header(struct archive_read *a,
345         struct archive_entry *entry)
346 {
347         struct zip *zip = (struct zip *)a->format->data;
348         int r;
349
350         a->archive.archive_format = ARCHIVE_FORMAT_ZIP;
351         if (a->archive.archive_format_name == NULL)
352                 a->archive.archive_format_name = "ZIP";
353
354         if (zip->zip_entries == NULL) {
355                 r = slurp_central_directory(a, zip);
356                 zip->entries_remaining = zip->central_directory_entries;
357                 if (r != ARCHIVE_OK)
358                         return r;
359                 zip->entry = zip->zip_entries;
360         } else {
361                 ++zip->entry;
362         }
363
364         if (zip->entries_remaining <= 0)
365                 return ARCHIVE_EOF;
366         --zip->entries_remaining;
367
368         /* TODO: If entries are sorted by offset within the file, we
369            should be able to skip here instead of seeking.  Skipping is
370            typically faster (easier for I/O layer to optimize). */
371         __archive_read_seek(a, zip->entry->local_header_offset, SEEK_SET);
372         zip->unconsumed = 0;
373         r = zip_read_local_file_header(a, entry, zip);
374         if (r != ARCHIVE_OK)
375                 return r;
376         if ((zip->entry->mode & AE_IFMT) == AE_IFLNK) {
377                 const void *p;
378                 size_t linkname_length = archive_entry_size(entry);
379
380                 archive_entry_set_size(entry, 0);
381                 p = __archive_read_ahead(a, linkname_length, NULL);
382                 if (p == NULL) {
383                         archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
384                             "Truncated Zip file");
385                         return ARCHIVE_FATAL;
386                 }
387
388                 if (archive_entry_copy_symlink_l(entry, p, linkname_length,
389                     NULL) != 0) {
390                         /* NOTE: If the last argument is NULL, this will
391                          * fail only by memeory allocation failure. */
392                         archive_set_error(&a->archive, ENOMEM,
393                             "Can't allocate memory for Symlink");
394                         return (ARCHIVE_FATAL);
395                 }
396                 /* TODO: handle character-set issues? */
397         }
398         return ARCHIVE_OK;
399 }
400
401 static int
402 archive_read_format_zip_streamable_bid(struct archive_read *a, int best_bid)
403 {
404         const char *p;
405
406         (void)best_bid; /* UNUSED */
407
408         if ((p = __archive_read_ahead(a, 4, NULL)) == NULL)
409                 return (-1);
410
411         /*
412          * Bid of 30 here is: 16 bits for "PK",
413          * next 16-bit field has four options (-2 bits).
414          * 16 + 16-2 = 30.
415          */
416         if (p[0] == 'P' && p[1] == 'K') {
417                 if ((p[2] == '\001' && p[3] == '\002')
418                     || (p[2] == '\003' && p[3] == '\004')
419                     || (p[2] == '\005' && p[3] == '\006')
420                     || (p[2] == '\007' && p[3] == '\010')
421                     || (p[2] == '0' && p[3] == '0'))
422                         return (30);
423         }
424
425         /* TODO: It's worth looking ahead a little bit for a valid
426          * PK signature.  In particular, that would make it possible
427          * to read some UUEncoded SFX files or SFX files coming from
428          * a network socket. */
429
430         return (0);
431 }
432
433 static int
434 archive_read_format_zip_options(struct archive_read *a,
435     const char *key, const char *val)
436 {
437         struct zip *zip;
438         int ret = ARCHIVE_FAILED;
439
440         zip = (struct zip *)(a->format->data);
441         if (strcmp(key, "compat-2x")  == 0) {
442                 /* Handle filnames as libarchive 2.x */
443                 zip->init_default_conversion = (val != NULL) ? 1 : 0;
444                 return (ARCHIVE_OK);
445         } else if (strcmp(key, "hdrcharset")  == 0) {
446                 if (val == NULL || val[0] == 0)
447                         archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
448                             "zip: hdrcharset option needs a character-set name");
449                 else {
450                         zip->sconv = archive_string_conversion_from_charset(
451                             &a->archive, val, 0);
452                         if (zip->sconv != NULL) {
453                                 if (strcmp(val, "UTF-8") == 0)
454                                         zip->sconv_utf8 = zip->sconv;
455                                 ret = ARCHIVE_OK;
456                         } else
457                                 ret = ARCHIVE_FATAL;
458                 }
459                 return (ret);
460         }
461
462         /* Note: The "warn" return is just to inform the options
463          * supervisor that we didn't handle it.  It will generate
464          * a suitable error if no one used this option. */
465         return (ARCHIVE_WARN);
466 }
467
468 static int
469 archive_read_format_zip_streamable_read_header(struct archive_read *a,
470     struct archive_entry *entry)
471 {
472         struct zip *zip;
473
474         a->archive.archive_format = ARCHIVE_FORMAT_ZIP;
475         if (a->archive.archive_format_name == NULL)
476                 a->archive.archive_format_name = "ZIP";
477
478         zip = (struct zip *)(a->format->data);
479
480         /* Make sure we have a zip_entry structure to use. */
481         if (zip->zip_entries == NULL) {
482                 zip->zip_entries = malloc(sizeof(struct zip_entry));
483                 if (zip->zip_entries == NULL) {
484                         archive_set_error(&a->archive, ENOMEM, "Out  of memory");
485                         return ARCHIVE_FATAL;
486                 }
487         }
488         zip->entry = zip->zip_entries;
489         memset(zip->entry, 0, sizeof(struct zip_entry));
490
491         /* Search ahead for the next local file header. */
492         __archive_read_consume(a, zip->unconsumed);
493         zip->unconsumed = 0;
494         for (;;) {
495                 int64_t skipped = 0;
496                 const char *p, *end;
497                 ssize_t bytes;
498
499                 p = __archive_read_ahead(a, 4, &bytes);
500                 if (p == NULL)
501                         return (ARCHIVE_FATAL);
502                 end = p + bytes;
503
504                 while (p + 4 <= end) {
505                         if (p[0] == 'P' && p[1] == 'K') {
506                                 if (p[2] == '\001' && p[3] == '\002')
507                                         /* Beginning of central directory. */
508                                         return (ARCHIVE_EOF);
509
510                                 if (p[2] == '\003' && p[3] == '\004') {
511                                         /* Regular file entry. */
512                                         __archive_read_consume(a, skipped);
513                                         return zip_read_local_file_header(a, entry, zip);
514                                 }
515
516                                 if (p[2] == '\005' && p[3] == '\006')
517                                         /* End of central directory. */
518                                         return (ARCHIVE_EOF);
519                         }
520                         ++p;
521                         ++skipped;
522                 }
523                 __archive_read_consume(a, skipped);
524         }
525 }
526
527 /*
528  * Assumes file pointer is at beginning of local file header.
529  */
530 static int
531 zip_read_local_file_header(struct archive_read *a, struct archive_entry *entry,
532     struct zip *zip)
533 {
534         const char *p;
535         const void *h;
536         const wchar_t *wp;
537         const char *cp;
538         size_t len, filename_length, extra_length;
539         struct archive_string_conv *sconv;
540         struct zip_entry *zip_entry = zip->entry;
541         uint32_t local_crc32;
542         int64_t compressed_size, uncompressed_size;
543         int ret = ARCHIVE_OK;
544         char version;
545
546         zip->decompress_init = 0;
547         zip->end_of_entry = 0;
548         zip->entry_uncompressed_bytes_read = 0;
549         zip->entry_compressed_bytes_read = 0;
550         zip->entry_crc32 = crc32(0, NULL, 0);
551
552         /* Setup default conversion. */
553         if (zip->sconv == NULL && !zip->init_default_conversion) {
554                 zip->sconv_default =
555                     archive_string_default_conversion_for_read(&(a->archive));
556                 zip->init_default_conversion = 1;
557         }
558
559         if ((p = __archive_read_ahead(a, 30, NULL)) == NULL) {
560                 archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
561                     "Truncated ZIP file header");
562                 return (ARCHIVE_FATAL);
563         }
564
565         if (memcmp(p, "PK\003\004", 4) != 0) {
566                 archive_set_error(&a->archive, -1, "Damaged Zip archive");
567                 return ARCHIVE_FATAL;
568         }
569         version = p[4];
570         zip_entry->system = p[5];
571         zip_entry->flags = archive_le16dec(p + 6);
572         zip_entry->compression = archive_le16dec(p + 8);
573         zip_entry->mtime = zip_time(p + 10);
574         local_crc32 = archive_le32dec(p + 14);
575         compressed_size = archive_le32dec(p + 18);
576         uncompressed_size = archive_le32dec(p + 22);
577         filename_length = archive_le16dec(p + 26);
578         extra_length = archive_le16dec(p + 28);
579
580         __archive_read_consume(a, 30);
581
582         if (zip->have_central_directory) {
583                 /* If we read the central dir entry, we must have size information
584                    as well, so ignore the length-at-end flag. */
585                 zip_entry->flags &= ~ZIP_LENGTH_AT_END;
586                 /* If we have values from both the local file header
587                    and the central directory, warn about mismatches
588                    which might indicate a damaged file.  But some
589                    writers always put zero in the local header; don't
590                    bother warning about that. */
591                 if (local_crc32 != 0 && local_crc32 != zip_entry->crc32) {
592                         archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
593                             "Inconsistent CRC32 values");
594                         ret = ARCHIVE_WARN;
595                 }
596                 if (compressed_size != 0
597                     && compressed_size != zip_entry->compressed_size) {
598                         archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
599                             "Inconsistent compressed size");
600                         ret = ARCHIVE_WARN;
601                 }
602                 if (uncompressed_size != 0
603                     && uncompressed_size != zip_entry->uncompressed_size) {
604                         archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
605                             "Inconsistent uncompressed size");
606                         ret = ARCHIVE_WARN;
607                 }
608         } else {
609                 /* If we don't have the CD info, use whatever we do have. */
610                 zip_entry->crc32 = local_crc32;
611                 zip_entry->compressed_size = compressed_size;
612                 zip_entry->uncompressed_size = uncompressed_size;
613         }
614
615         /* Read the filename. */
616         if ((h = __archive_read_ahead(a, filename_length, NULL)) == NULL) {
617                 archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
618                     "Truncated ZIP file header");
619                 return (ARCHIVE_FATAL);
620         }
621         if (zip_entry->flags & ZIP_UTF8_NAME) {
622                 /* The filename is stored to be UTF-8. */
623                 if (zip->sconv_utf8 == NULL) {
624                         zip->sconv_utf8 =
625                             archive_string_conversion_from_charset(
626                                 &a->archive, "UTF-8", 1);
627                         if (zip->sconv_utf8 == NULL)
628                                 return (ARCHIVE_FATAL);
629                 }
630                 sconv = zip->sconv_utf8;
631         } else if (zip->sconv != NULL)
632                 sconv = zip->sconv;
633         else
634                 sconv = zip->sconv_default;
635
636         if (archive_entry_copy_pathname_l(entry,
637             h, filename_length, sconv) != 0) {
638                 if (errno == ENOMEM) {
639                         archive_set_error(&a->archive, ENOMEM,
640                             "Can't allocate memory for Pathname");
641                         return (ARCHIVE_FATAL);
642                 }
643                 archive_set_error(&a->archive,
644                     ARCHIVE_ERRNO_FILE_FORMAT,
645                     "Pathname cannot be converted "
646                     "from %s to current locale.",
647                     archive_string_conversion_charset_name(sconv));
648                 ret = ARCHIVE_WARN;
649         }
650         __archive_read_consume(a, filename_length);
651
652         if (zip_entry->mode == 0) {
653                 /* Especially in streaming mode, we can end up
654                    here without having seen any mode information.
655                    Guess from the filename. */
656                 wp = archive_entry_pathname_w(entry);
657                 if (wp != NULL) {
658                         len = wcslen(wp);
659                         if (len > 0 && wp[len - 1] == L'/')
660                                 zip_entry->mode = AE_IFDIR | 0777;
661                         else
662                                 zip_entry->mode = AE_IFREG | 0777;
663                 } else {
664                         cp = archive_entry_pathname(entry);
665                         len = (cp != NULL)?strlen(cp):0;
666                         if (len > 0 && cp[len - 1] == '/')
667                                 zip_entry->mode = AE_IFDIR | 0777;
668                         else
669                                 zip_entry->mode = AE_IFREG | 0777;
670                 }
671         }
672
673         /* Read the extra data. */
674         if ((h = __archive_read_ahead(a, extra_length, NULL)) == NULL) {
675                 archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
676                     "Truncated ZIP file header");
677                 return (ARCHIVE_FATAL);
678         }
679         process_extra(h, extra_length, zip_entry);
680         __archive_read_consume(a, extra_length);
681
682         /* Populate some additional entry fields: */
683         archive_entry_set_mode(entry, zip_entry->mode);
684         archive_entry_set_uid(entry, zip_entry->uid);
685         archive_entry_set_gid(entry, zip_entry->gid);
686         archive_entry_set_mtime(entry, zip_entry->mtime, 0);
687         archive_entry_set_ctime(entry, zip_entry->ctime, 0);
688         archive_entry_set_atime(entry, zip_entry->atime, 0);
689         /* Set the size only if it's meaningful. */
690         if (0 == (zip_entry->flags & ZIP_LENGTH_AT_END))
691                 archive_entry_set_size(entry, zip_entry->uncompressed_size);
692
693         zip->entry_bytes_remaining = zip_entry->compressed_size;
694
695         /* If there's no body, force read_data() to return EOF immediately. */
696         if (0 == (zip_entry->flags & ZIP_LENGTH_AT_END)
697             && zip->entry_bytes_remaining < 1)
698                 zip->end_of_entry = 1;
699
700         /* Set up a more descriptive format name. */
701         sprintf(zip->format_name, "ZIP %d.%d (%s)",
702             version / 10, version % 10,
703             compression_name(zip->entry->compression));
704         a->archive.archive_format_name = zip->format_name;
705
706         return (ret);
707 }
708
709 static const char *
710 compression_name(int compression)
711 {
712         static const char *compression_names[] = {
713                 "uncompressed",
714                 "shrinking",
715                 "reduced-1",
716                 "reduced-2",
717                 "reduced-3",
718                 "reduced-4",
719                 "imploded",
720                 "reserved",
721                 "deflation"
722         };
723
724         if (0 <= compression && compression <
725             (int)(sizeof(compression_names)/sizeof(compression_names[0])))
726                 return compression_names[compression];
727         else
728                 return "??";
729 }
730
731 /* Convert an MSDOS-style date/time into Unix-style time. */
732 static time_t
733 zip_time(const char *p)
734 {
735         int msTime, msDate;
736         struct tm ts;
737
738         msTime = (0xff & (unsigned)p[0]) + 256 * (0xff & (unsigned)p[1]);
739         msDate = (0xff & (unsigned)p[2]) + 256 * (0xff & (unsigned)p[3]);
740
741         memset(&ts, 0, sizeof(ts));
742         ts.tm_year = ((msDate >> 9) & 0x7f) + 80; /* Years since 1900. */
743         ts.tm_mon = ((msDate >> 5) & 0x0f) - 1; /* Month number. */
744         ts.tm_mday = msDate & 0x1f; /* Day of month. */
745         ts.tm_hour = (msTime >> 11) & 0x1f;
746         ts.tm_min = (msTime >> 5) & 0x3f;
747         ts.tm_sec = (msTime << 1) & 0x3e;
748         ts.tm_isdst = -1;
749         return mktime(&ts);
750 }
751
752 static int
753 archive_read_format_zip_read_data(struct archive_read *a,
754     const void **buff, size_t *size, int64_t *offset)
755 {
756         int r;
757         struct zip *zip = (struct zip *)(a->format->data);
758
759         *offset = zip->entry_uncompressed_bytes_read;
760         *size = 0;
761         *buff = NULL;
762
763         /* If we hit end-of-entry last time, return ARCHIVE_EOF. */
764         if (zip->end_of_entry)
765                 return (ARCHIVE_EOF);
766
767         /* Return EOF immediately if this is a non-regular file. */
768         if (AE_IFREG != (zip->entry->mode & AE_IFMT))
769                 return (ARCHIVE_EOF);
770
771         if (zip->entry->flags & (ZIP_ENCRYPTED | ZIP_STRONG_ENCRYPTED)) {
772                 archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
773                     "Encrypted file is unsupported");
774                 return (ARCHIVE_FAILED);
775         }
776
777         __archive_read_consume(a, zip->unconsumed);
778         zip->unconsumed = 0;
779
780         switch(zip->entry->compression) {
781         case 0:  /* No compression. */
782                 r =  zip_read_data_none(a, buff, size, offset);
783                 break;
784 #ifdef HAVE_ZLIB_H
785         case 8: /* Deflate compression. */
786                 r =  zip_read_data_deflate(a, buff, size, offset);
787                 break;
788 #endif
789         default: /* Unsupported compression. */
790                 /* Return a warning. */
791                 archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
792                     "Unsupported ZIP compression method (%s)",
793                     compression_name(zip->entry->compression));
794                 /* We can't decompress this entry, but we will
795                  * be able to skip() it and try the next entry. */
796                 return (ARCHIVE_FAILED);
797                 break;
798         }
799         if (r != ARCHIVE_OK)
800                 return (r);
801         /* Update checksum */
802         if (*size)
803                 zip->entry_crc32 = crc32(zip->entry_crc32, *buff, *size);
804         /* If we hit the end, swallow any end-of-data marker. */
805         if (zip->end_of_entry) {
806                 /* Check file size, CRC against these values. */
807                 if (zip->entry->compressed_size != zip->entry_compressed_bytes_read) {
808                         archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
809                             "ZIP compressed data is wrong size (read %jd, expected %jd)",
810                             (intmax_t)zip->entry_compressed_bytes_read,
811                             (intmax_t)zip->entry->compressed_size);
812                         return (ARCHIVE_WARN);
813                 }
814                 /* Size field only stores the lower 32 bits of the actual
815                  * size. */
816                 if ((zip->entry->uncompressed_size & UINT32_MAX)
817                     != (zip->entry_uncompressed_bytes_read & UINT32_MAX)) {
818                         archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
819                             "ZIP uncompressed data is wrong size (read %jd, expected %jd)",
820                             (intmax_t)zip->entry_uncompressed_bytes_read,
821                             (intmax_t)zip->entry->uncompressed_size);
822                         return (ARCHIVE_WARN);
823                 }
824                 /* Check computed CRC against header */
825                 if (zip->entry->crc32 != zip->entry_crc32) {
826                         archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
827                             "ZIP bad CRC: 0x%lx should be 0x%lx",
828                             (unsigned long)zip->entry_crc32,
829                             (unsigned long)zip->entry->crc32);
830                         return (ARCHIVE_WARN);
831                 }
832         }
833
834         return (ARCHIVE_OK);
835 }
836
837 /*
838  * Read "uncompressed" data.  There are three cases:
839  *  1) We know the size of the data.  This is always true for the
840  * seeking reader (we've examined the Central Directory already).
841  *  2) ZIP_LENGTH_AT_END was set, but only the CRC was deferred.
842  * Info-ZIP seems to do this; we know the size but have to grab
843  * the CRC from the data descriptor afterwards.
844  *  3) We're streaming and ZIP_LENGTH_AT_END was specified and
845  * we have no size information.  In this case, we can do pretty
846  * well by watching for the data descriptor record.  The data
847  * descriptor is 16 bytes and includes a computed CRC that should
848  * provide a strong check.
849  *
850  * TODO: Technically, the PK\007\010 signature is optional.
851  * In the original spec, the data descriptor contained CRC
852  * and size fields but had no leading signature.  In practice,
853  * newer writers seem to provide the signature pretty consistently,
854  * but we might need to do something more complex here if
855  * we want to handle older archives that lack that signature.
856  *
857  * Returns ARCHIVE_OK if successful, ARCHIVE_FATAL otherwise, sets
858  * zip->end_of_entry if it consumes all of the data.
859  */
860 static int
861 zip_read_data_none(struct archive_read *a, const void **_buff,
862     size_t *size, int64_t *offset)
863 {
864         struct zip *zip;
865         const char *buff;
866         ssize_t bytes_avail;
867
868         (void)offset; /* UNUSED */
869
870         zip = (struct zip *)(a->format->data);
871
872         if (zip->entry->flags & ZIP_LENGTH_AT_END) {
873                 const char *p;
874
875                 /* Grab at least 16 bytes. */
876                 buff = __archive_read_ahead(a, 16, &bytes_avail);
877                 if (bytes_avail < 16) {
878                         /* Zip archives have end-of-archive markers
879                            that are longer than this, so a failure to get at
880                            least 16 bytes really does indicate a truncated
881                            file. */
882                         archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
883                             "Truncated ZIP file data");
884                         return (ARCHIVE_FATAL);
885                 }
886                 /* Check for a complete PK\007\010 signature. */
887                 p = buff;
888                 if (p[0] == 'P' && p[1] == 'K' 
889                     && p[2] == '\007' && p[3] == '\010'
890                     && archive_le32dec(p + 4) == zip->entry_crc32
891                     && archive_le32dec(p + 8) == zip->entry_compressed_bytes_read
892                     && archive_le32dec(p + 12) == zip->entry_uncompressed_bytes_read) {
893                         zip->entry->crc32 = archive_le32dec(p + 4);
894                         zip->entry->compressed_size = archive_le32dec(p + 8);
895                         zip->entry->uncompressed_size = archive_le32dec(p + 12);
896                         zip->end_of_entry = 1;
897                         zip->unconsumed = 16;
898                         return (ARCHIVE_OK);
899                 }
900                 /* If not at EOF, ensure we consume at least one byte. */
901                 ++p;
902
903                 /* Scan forward until we see where a PK\007\010 signature might be. */
904                 /* Return bytes up until that point.  On the next call, the code
905                    above will verify the data descriptor. */
906                 while (p < buff + bytes_avail - 4) {
907                         if (p[3] == 'P') { p += 3; }
908                         else if (p[3] == 'K') { p += 2; }
909                         else if (p[3] == '\007') { p += 1; }
910                         else if (p[3] == '\010' && p[2] == '\007'
911                             && p[1] == 'K' && p[0] == 'P') {
912                                 break;
913                         } else { p += 4; }
914                 }
915                 bytes_avail = p - buff;
916         } else {
917                 if (zip->entry_bytes_remaining == 0) {
918                         zip->end_of_entry = 1;
919                         return (ARCHIVE_OK);
920                 }
921                 /* Grab a bunch of bytes. */
922                 buff = __archive_read_ahead(a, 1, &bytes_avail);
923                 if (bytes_avail <= 0) {
924                         archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
925                             "Truncated ZIP file data");
926                         return (ARCHIVE_FATAL);
927                 }
928                 if (bytes_avail > zip->entry_bytes_remaining)
929                         bytes_avail = zip->entry_bytes_remaining;
930         }
931         *size = bytes_avail;
932         zip->entry_bytes_remaining -= bytes_avail;
933         zip->entry_uncompressed_bytes_read += bytes_avail;
934         zip->entry_compressed_bytes_read += bytes_avail;
935         zip->unconsumed += bytes_avail;
936         *_buff = buff;
937         return (ARCHIVE_OK);
938 }
939
940 #ifdef HAVE_ZLIB_H
941 static int
942 zip_read_data_deflate(struct archive_read *a, const void **buff,
943     size_t *size, int64_t *offset)
944 {
945         struct zip *zip;
946         ssize_t bytes_avail;
947         const void *compressed_buff;
948         int r;
949
950         (void)offset; /* UNUSED */
951
952         zip = (struct zip *)(a->format->data);
953
954         /* If the buffer hasn't been allocated, allocate it now. */
955         if (zip->uncompressed_buffer == NULL) {
956                 zip->uncompressed_buffer_size = 256 * 1024;
957                 zip->uncompressed_buffer
958                     = (unsigned char *)malloc(zip->uncompressed_buffer_size);
959                 if (zip->uncompressed_buffer == NULL) {
960                         archive_set_error(&a->archive, ENOMEM,
961                             "No memory for ZIP decompression");
962                         return (ARCHIVE_FATAL);
963                 }
964         }
965
966         /* If we haven't yet read any data, initialize the decompressor. */
967         if (!zip->decompress_init) {
968                 if (zip->stream_valid)
969                         r = inflateReset(&zip->stream);
970                 else
971                         r = inflateInit2(&zip->stream,
972                             -15 /* Don't check for zlib header */);
973                 if (r != Z_OK) {
974                         archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
975                             "Can't initialize ZIP decompression.");
976                         return (ARCHIVE_FATAL);
977                 }
978                 /* Stream structure has been set up. */
979                 zip->stream_valid = 1;
980                 /* We've initialized decompression for this stream. */
981                 zip->decompress_init = 1;
982         }
983
984         /*
985          * Note: '1' here is a performance optimization.
986          * Recall that the decompression layer returns a count of
987          * available bytes; asking for more than that forces the
988          * decompressor to combine reads by copying data.
989          */
990         compressed_buff = __archive_read_ahead(a, 1, &bytes_avail);
991         if (0 == (zip->entry->flags & ZIP_LENGTH_AT_END)
992             && bytes_avail > zip->entry_bytes_remaining) {
993                 bytes_avail = zip->entry_bytes_remaining;
994         }
995         if (bytes_avail <= 0) {
996                 archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
997                     "Truncated ZIP file body");
998                 return (ARCHIVE_FATAL);
999         }
1000
1001         /*
1002          * A bug in zlib.h: stream.next_in should be marked 'const'
1003          * but isn't (the library never alters data through the
1004          * next_in pointer, only reads it).  The result: this ugly
1005          * cast to remove 'const'.
1006          */
1007         zip->stream.next_in = (Bytef *)(uintptr_t)(const void *)compressed_buff;
1008         zip->stream.avail_in = bytes_avail;
1009         zip->stream.total_in = 0;
1010         zip->stream.next_out = zip->uncompressed_buffer;
1011         zip->stream.avail_out = zip->uncompressed_buffer_size;
1012         zip->stream.total_out = 0;
1013
1014         r = inflate(&zip->stream, 0);
1015         switch (r) {
1016         case Z_OK:
1017                 break;
1018         case Z_STREAM_END:
1019                 zip->end_of_entry = 1;
1020                 break;
1021         case Z_MEM_ERROR:
1022                 archive_set_error(&a->archive, ENOMEM,
1023                     "Out of memory for ZIP decompression");
1024                 return (ARCHIVE_FATAL);
1025         default:
1026                 archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
1027                     "ZIP decompression failed (%d)", r);
1028                 return (ARCHIVE_FATAL);
1029         }
1030
1031         /* Consume as much as the compressor actually used. */
1032         bytes_avail = zip->stream.total_in;
1033         __archive_read_consume(a, bytes_avail);
1034         zip->entry_bytes_remaining -= bytes_avail;
1035         zip->entry_compressed_bytes_read += bytes_avail;
1036
1037         *size = zip->stream.total_out;
1038         zip->entry_uncompressed_bytes_read += zip->stream.total_out;
1039         *buff = zip->uncompressed_buffer;
1040
1041         if (zip->end_of_entry && (zip->entry->flags & ZIP_LENGTH_AT_END)) {
1042                 const char *p;
1043
1044                 if (NULL == (p = __archive_read_ahead(a, 16, NULL))) {
1045                         archive_set_error(&a->archive,
1046                             ARCHIVE_ERRNO_FILE_FORMAT,
1047                             "Truncated ZIP end-of-file record");
1048                         return (ARCHIVE_FATAL);
1049                 }
1050                 /* Consume the optional PK\007\010 marker. */
1051                 if (p[0] == 'P' && p[1] == 'K' && p[2] == '\007' && p[3] == '\010') {
1052                         zip->entry->crc32 = archive_le32dec(p + 4);
1053                         zip->entry->compressed_size = archive_le32dec(p + 8);
1054                         zip->entry->uncompressed_size = archive_le32dec(p + 12);
1055                         zip->unconsumed = 16;
1056                 }
1057         }
1058
1059         return (ARCHIVE_OK);
1060 }
1061 #endif
1062
1063 static int
1064 archive_read_format_zip_read_data_skip(struct archive_read *a)
1065 {
1066         struct zip *zip;
1067
1068         zip = (struct zip *)(a->format->data);
1069
1070         /* If we've already read to end of data, we're done. */
1071         if (zip->end_of_entry)
1072                 return (ARCHIVE_OK);
1073         /* If we're seeking, we're done. */
1074         if (zip->have_central_directory)
1075                 return (ARCHIVE_OK);
1076
1077         /* So we know we're streaming... */
1078         if (0 == (zip->entry->flags & ZIP_LENGTH_AT_END)) {
1079                 /* We know the compressed length, so we can just skip. */
1080                 int64_t bytes_skipped = __archive_read_consume(a,
1081                     zip->entry_bytes_remaining + zip->unconsumed);
1082                 if (bytes_skipped < 0)
1083                         return (ARCHIVE_FATAL);
1084                 zip->unconsumed = 0;
1085                 return (ARCHIVE_OK);
1086         }
1087
1088         /* We're streaming and we don't know the length. */
1089         /* If the body is compressed and we know the format, we can
1090          * find an exact end-of-entry by decompressing it. */
1091         switch (zip->entry->compression) {
1092 #ifdef HAVE_ZLIB_H
1093         case 8: /* Deflate compression. */
1094                 while (!zip->end_of_entry) {
1095                         int64_t offset = 0;
1096                         const void *buff = NULL;
1097                         size_t size = 0;
1098                         int r;
1099                         r =  zip_read_data_deflate(a, &buff, &size, &offset);
1100                         if (r != ARCHIVE_OK)
1101                                 return (r);
1102                 }
1103                 break;
1104 #endif
1105         default: /* Uncompressed or unknown. */
1106                 /* Scan for a PK\007\010 signature. */
1107                 __archive_read_consume(a, zip->unconsumed);
1108                 zip->unconsumed = 0;
1109                 for (;;) {
1110                         const char *p, *buff;
1111                         ssize_t bytes_avail;
1112                         buff = __archive_read_ahead(a, 16, &bytes_avail);
1113                         if (bytes_avail < 16) {
1114                                 archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1115                                     "Truncated ZIP file data");
1116                                 return (ARCHIVE_FATAL);
1117                         }
1118                         p = buff;
1119                         while (p <= buff + bytes_avail - 16) {
1120                                 if (p[3] == 'P') { p += 3; }
1121                                 else if (p[3] == 'K') { p += 2; }
1122                                 else if (p[3] == '\007') { p += 1; }
1123                                 else if (p[3] == '\010' && p[2] == '\007'
1124                                     && p[1] == 'K' && p[0] == 'P') {
1125                                         __archive_read_consume(a, p - buff + 16);
1126                                         return ARCHIVE_OK;
1127                                 } else { p += 4; }
1128                         }
1129                         __archive_read_consume(a, p - buff);
1130                 }
1131         }
1132         return ARCHIVE_OK;
1133 }
1134
1135 static int
1136 archive_read_format_zip_cleanup(struct archive_read *a)
1137 {
1138         struct zip *zip;
1139
1140         zip = (struct zip *)(a->format->data);
1141 #ifdef HAVE_ZLIB_H
1142         if (zip->stream_valid)
1143                 inflateEnd(&zip->stream);
1144 #endif
1145         free(zip->zip_entries);
1146         free(zip->uncompressed_buffer);
1147         archive_string_free(&(zip->extra));
1148         free(zip);
1149         (a->format->data) = NULL;
1150         return (ARCHIVE_OK);
1151 }
1152
1153 /*
1154  * The extra data is stored as a list of
1155  *      id1+size1+data1 + id2+size2+data2 ...
1156  *  triplets.  id and size are 2 bytes each.
1157  */
1158 static void
1159 process_extra(const char *p, size_t extra_length, struct zip_entry* zip_entry)
1160 {
1161         unsigned offset = 0;
1162
1163         while (offset < extra_length - 4)
1164         {
1165                 unsigned short headerid = archive_le16dec(p + offset);
1166                 unsigned short datasize = archive_le16dec(p + offset + 2);
1167                 offset += 4;
1168                 if (offset + datasize > extra_length)
1169                         break;
1170 #ifdef DEBUG
1171                 fprintf(stderr, "Header id 0x%x, length %d\n",
1172                     headerid, datasize);
1173 #endif
1174                 switch (headerid) {
1175                 case 0x0001:
1176                         /* Zip64 extended information extra field. */
1177                         if (datasize >= 8)
1178                                 zip_entry->uncompressed_size =
1179                                     archive_le64dec(p + offset);
1180                         if (datasize >= 16)
1181                                 zip_entry->compressed_size =
1182                                     archive_le64dec(p + offset + 8);
1183                         break;
1184                 case 0x5455:
1185                 {
1186                         /* Extended time field "UT". */
1187                         int flags = p[offset];
1188                         offset++;
1189                         datasize--;
1190                         /* Flag bits indicate which dates are present. */
1191                         if (flags & 0x01)
1192                         {
1193 #ifdef DEBUG
1194                                 fprintf(stderr, "mtime: %lld -> %d\n",
1195                                     (long long)zip_entry->mtime,
1196                                     archive_le32dec(p + offset));
1197 #endif
1198                                 if (datasize < 4)
1199                                         break;
1200                                 zip_entry->mtime = archive_le32dec(p + offset);
1201                                 offset += 4;
1202                                 datasize -= 4;
1203                         }
1204                         if (flags & 0x02)
1205                         {
1206                                 if (datasize < 4)
1207                                         break;
1208                                 zip_entry->atime = archive_le32dec(p + offset);
1209                                 offset += 4;
1210                                 datasize -= 4;
1211                         }
1212                         if (flags & 0x04)
1213                         {
1214                                 if (datasize < 4)
1215                                         break;
1216                                 zip_entry->ctime = archive_le32dec(p + offset);
1217                                 offset += 4;
1218                                 datasize -= 4;
1219                         }
1220                         break;
1221                 }
1222                 case 0x5855:
1223                 {
1224                         /* Info-ZIP Unix Extra Field (old version) "UX". */
1225                         if (datasize >= 8) {
1226                                 zip_entry->atime = archive_le32dec(p + offset);
1227                                 zip_entry->mtime = archive_le32dec(p + offset + 4);
1228                         }
1229                         if (datasize >= 12) {
1230                                 zip_entry->uid = archive_le16dec(p + offset + 8);
1231                                 zip_entry->gid = archive_le16dec(p + offset + 10);
1232                         }
1233                         break;
1234                 }
1235                 case 0x7855:
1236                         /* Info-ZIP Unix Extra Field (type 2) "Ux". */
1237 #ifdef DEBUG
1238                         fprintf(stderr, "uid %d gid %d\n",
1239                             archive_le16dec(p + offset),
1240                             archive_le16dec(p + offset + 2));
1241 #endif
1242                         if (datasize >= 2)
1243                                 zip_entry->uid = archive_le16dec(p + offset);
1244                         if (datasize >= 4)
1245                                 zip_entry->gid = archive_le16dec(p + offset + 2);
1246                         break;
1247                 case 0x7875:
1248                 {
1249                         /* Info-Zip Unix Extra Field (type 3) "ux". */
1250                         int uidsize = 0, gidsize = 0;
1251
1252                         if (datasize >= 1 && p[offset] == 1) {/* version=1 */
1253                                 if (datasize >= 4) {
1254                                         /* get a uid size. */
1255                                         uidsize = p[offset+1];
1256                                         if (uidsize == 2)
1257                                                 zip_entry->uid = archive_le16dec(
1258                                                      p + offset + 2);
1259                                         else if (uidsize == 4 && datasize >= 6)
1260                                                 zip_entry->uid = archive_le32dec(
1261                                                      p + offset + 2);
1262                                 }
1263                                 if (datasize >= (2 + uidsize + 3)) {
1264                                         /* get a gid size. */
1265                                         gidsize = p[offset+2+uidsize];
1266                                         if (gidsize == 2)
1267                                                 zip_entry->gid = archive_le16dec(
1268                                                     p+offset+2+uidsize+1);
1269                                         else if (gidsize == 4 &&
1270                                             datasize >= (2 + uidsize + 5))
1271                                                 zip_entry->gid = archive_le32dec(
1272                                                     p+offset+2+uidsize+1);
1273                                 }
1274                         }
1275                         break;
1276                 }
1277                 default:
1278                         break;
1279                 }
1280                 offset += datasize;
1281         }
1282 #ifdef DEBUG
1283         if (offset != extra_length)
1284         {
1285                 fprintf(stderr,
1286                     "Extra data field contents do not match reported size!\n");
1287         }
1288 #endif
1289 }