]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - libarchive/archive_read_support_format_zip.c
Update libarchive's 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 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 + 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                 ret = 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         } else
460                 archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
461                     "zip: unknown keyword ``%s''", key);
462
463         return (ret);
464 }
465
466 static int
467 archive_read_format_zip_streamable_read_header(struct archive_read *a,
468     struct archive_entry *entry)
469 {
470         struct zip *zip;
471
472         a->archive.archive_format = ARCHIVE_FORMAT_ZIP;
473         if (a->archive.archive_format_name == NULL)
474                 a->archive.archive_format_name = "ZIP";
475
476         zip = (struct zip *)(a->format->data);
477
478         /* Make sure we have a zip_entry structure to use. */
479         if (zip->zip_entries == NULL) {
480                 zip->zip_entries = malloc(sizeof(struct zip_entry));
481                 if (zip->zip_entries == NULL) {
482                         archive_set_error(&a->archive, ENOMEM, "Out  of memory");
483                         return ARCHIVE_FATAL;
484                 }
485         }
486         zip->entry = zip->zip_entries;
487         memset(zip->entry, 0, sizeof(struct zip_entry));
488
489         /* Search ahead for the next local file header. */
490         __archive_read_consume(a, zip->unconsumed);
491         zip->unconsumed = 0;
492         for (;;) {
493                 int64_t skipped = 0;
494                 const char *p, *end;
495                 ssize_t bytes;
496
497                 p = __archive_read_ahead(a, 4, &bytes);
498                 if (p == NULL)
499                         return (ARCHIVE_FATAL);
500                 end = p + bytes;
501
502                 while (p + 4 <= end) {
503                         if (p[0] == 'P' && p[1] == 'K') {
504                                 if (p[2] == '\001' && p[3] == '\002')
505                                         /* Beginning of central directory. */
506                                         return (ARCHIVE_EOF);
507
508                                 if (p[2] == '\003' && p[3] == '\004') {
509                                         /* Regular file entry. */
510                                         __archive_read_consume(a, skipped);
511                                         return zip_read_local_file_header(a, entry, zip);
512                                 }
513
514                                 if (p[2] == '\005' && p[3] == '\006')
515                                         /* End of central directory. */
516                                         return (ARCHIVE_EOF);
517                         }
518                         ++p;
519                         ++skipped;
520                 }
521                 __archive_read_consume(a, skipped);
522         }
523 }
524
525 /*
526  * Assumes file pointer is at beginning of local file header.
527  */
528 static int
529 zip_read_local_file_header(struct archive_read *a, struct archive_entry *entry,
530     struct zip *zip)
531 {
532         const char *p;
533         const void *h;
534         const wchar_t *wp;
535         const char *cp;
536         size_t len, filename_length, extra_length;
537         struct archive_string_conv *sconv;
538         struct zip_entry *zip_entry = zip->entry;
539         uint32_t local_crc32;
540         int64_t compressed_size, uncompressed_size;
541         int ret = ARCHIVE_OK;
542         char version;
543
544         zip->decompress_init = 0;
545         zip->end_of_entry = 0;
546         zip->entry_uncompressed_bytes_read = 0;
547         zip->entry_compressed_bytes_read = 0;
548         zip->entry_crc32 = crc32(0, NULL, 0);
549
550         /* Setup default conversion. */
551         if (zip->sconv == NULL && !zip->init_default_conversion) {
552                 zip->sconv_default =
553                     archive_string_default_conversion_for_read(&(a->archive));
554                 zip->init_default_conversion = 1;
555         }
556
557         if ((p = __archive_read_ahead(a, 30, NULL)) == NULL) {
558                 archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
559                     "Truncated ZIP file header");
560                 return (ARCHIVE_FATAL);
561         }
562
563         if (memcmp(p, "PK\003\004", 4) != 0) {
564                 archive_set_error(&a->archive, -1, "Damaged Zip archive");
565                 return ARCHIVE_FATAL;
566         }
567         version = p[4];
568         zip_entry->system = p[5];
569         zip_entry->flags = archive_le16dec(p + 6);
570         zip_entry->compression = archive_le16dec(p + 8);
571         zip_entry->mtime = zip_time(p + 10);
572         local_crc32 = archive_le32dec(p + 14);
573         compressed_size = archive_le32dec(p + 18);
574         uncompressed_size = archive_le32dec(p + 22);
575         filename_length = archive_le16dec(p + 26);
576         extra_length = archive_le16dec(p + 28);
577
578         __archive_read_consume(a, 30);
579
580         if (zip->have_central_directory) {
581                 /* If we read the central dir entry, we must have size information
582                    as well, so ignore the length-at-end flag. */
583                 zip_entry->flags &= ~ZIP_LENGTH_AT_END;
584                 /* If we have values from both the local file header
585                    and the central directory, warn about mismatches
586                    which might indicate a damaged file.  But some
587                    writers always put zero in the local header; don't
588                    bother warning about that. */
589                 if (local_crc32 != 0 && local_crc32 != zip_entry->crc32) {
590                         archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
591                             "Inconsistent CRC32 values");
592                         ret = ARCHIVE_WARN;
593                 }
594                 if (compressed_size != 0
595                     && compressed_size != zip_entry->compressed_size) {
596                         archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
597                             "Inconsistent compressed size");
598                         ret = ARCHIVE_WARN;
599                 }
600                 if (uncompressed_size != 0
601                     && uncompressed_size != zip_entry->uncompressed_size) {
602                         archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
603                             "Inconsistent uncompressed size");
604                         ret = ARCHIVE_WARN;
605                 }
606         } else {
607                 /* If we don't have the CD info, use whatever we do have. */
608                 zip_entry->crc32 = local_crc32;
609                 zip_entry->compressed_size = compressed_size;
610                 zip_entry->uncompressed_size = uncompressed_size;
611         }
612
613         /* Read the filename. */
614         if ((h = __archive_read_ahead(a, filename_length, NULL)) == NULL) {
615                 archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
616                     "Truncated ZIP file header");
617                 return (ARCHIVE_FATAL);
618         }
619         if (zip_entry->flags & ZIP_UTF8_NAME) {
620                 /* The filename is stored to be UTF-8. */
621                 if (zip->sconv_utf8 == NULL) {
622                         zip->sconv_utf8 =
623                             archive_string_conversion_from_charset(
624                                 &a->archive, "UTF-8", 1);
625                         if (zip->sconv_utf8 == NULL)
626                                 return (ARCHIVE_FATAL);
627                 }
628                 sconv = zip->sconv_utf8;
629         } else if (zip->sconv != NULL)
630                 sconv = zip->sconv;
631         else
632                 sconv = zip->sconv_default;
633
634         if (archive_entry_copy_pathname_l(entry,
635             h, filename_length, sconv) != 0) {
636                 if (errno == ENOMEM) {
637                         archive_set_error(&a->archive, ENOMEM,
638                             "Can't allocate memory for Pathname");
639                         return (ARCHIVE_FATAL);
640                 }
641                 archive_set_error(&a->archive,
642                     ARCHIVE_ERRNO_FILE_FORMAT,
643                     "Pathname cannot be converted "
644                     "from %s to current locale.",
645                     archive_string_conversion_charset_name(sconv));
646                 ret = ARCHIVE_WARN;
647         }
648         __archive_read_consume(a, filename_length);
649
650         if (zip_entry->mode == 0) {
651                 /* Especially in streaming mode, we can end up
652                    here without having seen any mode information.
653                    Guess from the filename. */
654                 wp = archive_entry_pathname_w(entry);
655                 if (wp != NULL) {
656                         len = wcslen(wp);
657                         if (len > 0 && wp[len - 1] == L'/')
658                                 zip_entry->mode = AE_IFDIR | 0777;
659                         else
660                                 zip_entry->mode = AE_IFREG | 0777;
661                 } else {
662                         cp = archive_entry_pathname(entry);
663                         len = (cp != NULL)?strlen(cp):0;
664                         if (len > 0 && cp[len - 1] == '/')
665                                 zip_entry->mode = AE_IFDIR | 0777;
666                         else
667                                 zip_entry->mode = AE_IFREG | 0777;
668                 }
669         }
670
671         /* Read the extra data. */
672         if ((h = __archive_read_ahead(a, extra_length, NULL)) == NULL) {
673                 archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
674                     "Truncated ZIP file header");
675                 return (ARCHIVE_FATAL);
676         }
677         process_extra(h, extra_length, zip_entry);
678         __archive_read_consume(a, extra_length);
679
680         /* Populate some additional entry fields: */
681         archive_entry_set_mode(entry, zip_entry->mode);
682         archive_entry_set_uid(entry, zip_entry->uid);
683         archive_entry_set_gid(entry, zip_entry->gid);
684         archive_entry_set_mtime(entry, zip_entry->mtime, 0);
685         archive_entry_set_ctime(entry, zip_entry->ctime, 0);
686         archive_entry_set_atime(entry, zip_entry->atime, 0);
687         /* Set the size only if it's meaningful. */
688         if (0 == (zip_entry->flags & ZIP_LENGTH_AT_END))
689                 archive_entry_set_size(entry, zip_entry->uncompressed_size);
690
691         zip->entry_bytes_remaining = zip_entry->compressed_size;
692
693         /* If there's no body, force read_data() to return EOF immediately. */
694         if (0 == (zip_entry->flags & ZIP_LENGTH_AT_END)
695             && zip->entry_bytes_remaining < 1)
696                 zip->end_of_entry = 1;
697
698         /* Set up a more descriptive format name. */
699         sprintf(zip->format_name, "ZIP %d.%d (%s)",
700             version / 10, version % 10,
701             compression_name(zip->entry->compression));
702         a->archive.archive_format_name = zip->format_name;
703
704         return (ret);
705 }
706
707 static const char *
708 compression_name(int compression)
709 {
710         static const char *compression_names[] = {
711                 "uncompressed",
712                 "shrinking",
713                 "reduced-1",
714                 "reduced-2",
715                 "reduced-3",
716                 "reduced-4",
717                 "imploded",
718                 "reserved",
719                 "deflation"
720         };
721
722         if (0 <= compression && compression <
723             (int)(sizeof(compression_names)/sizeof(compression_names[0])))
724                 return compression_names[compression];
725         else
726                 return "??";
727 }
728
729 /* Convert an MSDOS-style date/time into Unix-style time. */
730 static time_t
731 zip_time(const char *p)
732 {
733         int msTime, msDate;
734         struct tm ts;
735
736         msTime = (0xff & (unsigned)p[0]) + 256 * (0xff & (unsigned)p[1]);
737         msDate = (0xff & (unsigned)p[2]) + 256 * (0xff & (unsigned)p[3]);
738
739         memset(&ts, 0, sizeof(ts));
740         ts.tm_year = ((msDate >> 9) & 0x7f) + 80; /* Years since 1900. */
741         ts.tm_mon = ((msDate >> 5) & 0x0f) - 1; /* Month number. */
742         ts.tm_mday = msDate & 0x1f; /* Day of month. */
743         ts.tm_hour = (msTime >> 11) & 0x1f;
744         ts.tm_min = (msTime >> 5) & 0x3f;
745         ts.tm_sec = (msTime << 1) & 0x3e;
746         ts.tm_isdst = -1;
747         return mktime(&ts);
748 }
749
750 static int
751 archive_read_format_zip_read_data(struct archive_read *a,
752     const void **buff, size_t *size, int64_t *offset)
753 {
754         int r;
755         struct zip *zip = (struct zip *)(a->format->data);
756
757         *offset = zip->entry_uncompressed_bytes_read;
758         *size = 0;
759         *buff = NULL;
760
761         /* If we hit end-of-entry last time, return ARCHIVE_EOF. */
762         if (zip->end_of_entry)
763                 return (ARCHIVE_EOF);
764
765         /* Return EOF immediately if this is a non-regular file. */
766         if (AE_IFREG != (zip->entry->mode & AE_IFMT))
767                 return (ARCHIVE_EOF);
768
769         if (zip->entry->flags & (ZIP_ENCRYPTED | ZIP_STRONG_ENCRYPTED)) {
770                 archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
771                     "Encrypted file is unsupported");
772                 return (ARCHIVE_FAILED);
773         }
774
775         __archive_read_consume(a, zip->unconsumed);
776         zip->unconsumed = 0;
777
778         switch(zip->entry->compression) {
779         case 0:  /* No compression. */
780                 r =  zip_read_data_none(a, buff, size, offset);
781                 break;
782 #ifdef HAVE_ZLIB_H
783         case 8: /* Deflate compression. */
784                 r =  zip_read_data_deflate(a, buff, size, offset);
785                 break;
786 #endif
787         default: /* Unsupported compression. */
788                 /* Return a warning. */
789                 archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
790                     "Unsupported ZIP compression method (%s)",
791                     compression_name(zip->entry->compression));
792                 /* We can't decompress this entry, but we will
793                  * be able to skip() it and try the next entry. */
794                 return (ARCHIVE_FAILED);
795                 break;
796         }
797         if (r != ARCHIVE_OK)
798                 return (r);
799         /* Update checksum */
800         if (*size)
801                 zip->entry_crc32 = crc32(zip->entry_crc32, *buff, *size);
802         /* If we hit the end, swallow any end-of-data marker. */
803         if (zip->end_of_entry) {
804                 /* Check file size, CRC against these values. */
805                 if (zip->entry->compressed_size != zip->entry_compressed_bytes_read) {
806                         archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
807                             "ZIP compressed data is wrong size (read %jd, expected %jd)",
808                             (intmax_t)zip->entry_compressed_bytes_read,
809                             (intmax_t)zip->entry->compressed_size);
810                         return (ARCHIVE_WARN);
811                 }
812                 /* Size field only stores the lower 32 bits of the actual
813                  * size. */
814                 if ((zip->entry->uncompressed_size & UINT32_MAX)
815                     != (zip->entry_uncompressed_bytes_read & UINT32_MAX)) {
816                         archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
817                             "ZIP uncompressed data is wrong size (read %jd, expected %jd)",
818                             (intmax_t)zip->entry_uncompressed_bytes_read,
819                             (intmax_t)zip->entry->uncompressed_size);
820                         return (ARCHIVE_WARN);
821                 }
822                 /* Check computed CRC against header */
823                 if (zip->entry->crc32 != zip->entry_crc32) {
824                         archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
825                             "ZIP bad CRC: 0x%lx should be 0x%lx",
826                             (unsigned long)zip->entry_crc32,
827                             (unsigned long)zip->entry->crc32);
828                         return (ARCHIVE_WARN);
829                 }
830         }
831
832         return (ARCHIVE_OK);
833 }
834
835 /*
836  * Read "uncompressed" data.  There are three cases:
837  *  1) We know the size of the data.  This is always true for the
838  * seeking reader (we've examined the Central Directory already).
839  *  2) ZIP_LENGTH_AT_END was set, but only the CRC was deferred.
840  * Info-ZIP seems to do this; we know the size but have to grab
841  * the CRC from the data descriptor afterwards.
842  *  3) We're streaming and ZIP_LENGTH_AT_END was specified and
843  * we have no size information.  In this case, we can do pretty
844  * well by watching for the data descriptor record.  The data
845  * descriptor is 16 bytes and includes a computed CRC that should
846  * provide a strong check.
847  *
848  * TODO: Technically, the PK\007\010 signature is optional.
849  * In the original spec, the data descriptor contained CRC
850  * and size fields but had no leading signature.  In practice,
851  * newer writers seem to provide the signature pretty consistently,
852  * but we might need to do something more complex here if
853  * we want to handle older archives that lack that signature.
854  *
855  * Returns ARCHIVE_OK if successful, ARCHIVE_FATAL otherwise, sets
856  * zip->end_of_entry if it consumes all of the data.
857  */
858 static int
859 zip_read_data_none(struct archive_read *a, const void **_buff,
860     size_t *size, int64_t *offset)
861 {
862         struct zip *zip;
863         const char *buff;
864         ssize_t bytes_avail;
865
866         (void)offset; /* UNUSED */
867
868         zip = (struct zip *)(a->format->data);
869
870         if (zip->entry->flags & ZIP_LENGTH_AT_END) {
871                 const char *p;
872
873                 /* Grab at least 16 bytes. */
874                 buff = __archive_read_ahead(a, 16, &bytes_avail);
875                 if (bytes_avail < 16) {
876                         /* Zip archives have end-of-archive markers
877                            that are longer than this, so a failure to get at
878                            least 16 bytes really does indicate a truncated
879                            file. */
880                         archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
881                             "Truncated ZIP file data");
882                         return (ARCHIVE_FATAL);
883                 }
884                 /* Check for a complete PK\007\010 signature. */
885                 p = buff;
886                 if (p[0] == 'P' && p[1] == 'K' 
887                     && p[2] == '\007' && p[3] == '\010'
888                     && archive_le32dec(p + 4) == zip->entry_crc32
889                     && archive_le32dec(p + 8) == zip->entry_compressed_bytes_read
890                     && archive_le32dec(p + 12) == zip->entry_uncompressed_bytes_read) {
891                         zip->entry->crc32 = archive_le32dec(p + 4);
892                         zip->entry->compressed_size = archive_le32dec(p + 8);
893                         zip->entry->uncompressed_size = archive_le32dec(p + 12);
894                         zip->end_of_entry = 1;
895                         zip->unconsumed = 16;
896                         return (ARCHIVE_OK);
897                 }
898                 /* If not at EOF, ensure we consume at least one byte. */
899                 ++p;
900
901                 /* Scan forward until we see where a PK\007\010 signature might be. */
902                 /* Return bytes up until that point.  On the next call, the code
903                    above will verify the data descriptor. */
904                 while (p < buff + bytes_avail - 4) {
905                         if (p[3] == 'P') { p += 3; }
906                         else if (p[3] == 'K') { p += 2; }
907                         else if (p[3] == '\007') { p += 1; }
908                         else if (p[3] == '\010' && p[2] == '\007'
909                             && p[1] == 'K' && p[0] == 'P') {
910                                 break;
911                         } else { p += 4; }
912                 }
913                 bytes_avail = p - buff;
914         } else {
915                 if (zip->entry_bytes_remaining == 0) {
916                         zip->end_of_entry = 1;
917                         return (ARCHIVE_OK);
918                 }
919                 /* Grab a bunch of bytes. */
920                 buff = __archive_read_ahead(a, 1, &bytes_avail);
921                 if (bytes_avail <= 0) {
922                         archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
923                             "Truncated ZIP file data");
924                         return (ARCHIVE_FATAL);
925                 }
926                 if (bytes_avail > zip->entry_bytes_remaining)
927                         bytes_avail = zip->entry_bytes_remaining;
928         }
929         *size = bytes_avail;
930         zip->entry_bytes_remaining -= bytes_avail;
931         zip->entry_uncompressed_bytes_read += bytes_avail;
932         zip->entry_compressed_bytes_read += bytes_avail;
933         zip->unconsumed += bytes_avail;
934         *_buff = buff;
935         return (ARCHIVE_OK);
936 }
937
938 #ifdef HAVE_ZLIB_H
939 static int
940 zip_read_data_deflate(struct archive_read *a, const void **buff,
941     size_t *size, int64_t *offset)
942 {
943         struct zip *zip;
944         ssize_t bytes_avail;
945         const void *compressed_buff;
946         int r;
947
948         (void)offset; /* UNUSED */
949
950         zip = (struct zip *)(a->format->data);
951
952         /* If the buffer hasn't been allocated, allocate it now. */
953         if (zip->uncompressed_buffer == NULL) {
954                 zip->uncompressed_buffer_size = 256 * 1024;
955                 zip->uncompressed_buffer
956                     = (unsigned char *)malloc(zip->uncompressed_buffer_size);
957                 if (zip->uncompressed_buffer == NULL) {
958                         archive_set_error(&a->archive, ENOMEM,
959                             "No memory for ZIP decompression");
960                         return (ARCHIVE_FATAL);
961                 }
962         }
963
964         /* If we haven't yet read any data, initialize the decompressor. */
965         if (!zip->decompress_init) {
966                 if (zip->stream_valid)
967                         r = inflateReset(&zip->stream);
968                 else
969                         r = inflateInit2(&zip->stream,
970                             -15 /* Don't check for zlib header */);
971                 if (r != Z_OK) {
972                         archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
973                             "Can't initialize ZIP decompression.");
974                         return (ARCHIVE_FATAL);
975                 }
976                 /* Stream structure has been set up. */
977                 zip->stream_valid = 1;
978                 /* We've initialized decompression for this stream. */
979                 zip->decompress_init = 1;
980         }
981
982         /*
983          * Note: '1' here is a performance optimization.
984          * Recall that the decompression layer returns a count of
985          * available bytes; asking for more than that forces the
986          * decompressor to combine reads by copying data.
987          */
988         compressed_buff = __archive_read_ahead(a, 1, &bytes_avail);
989         if (0 == (zip->entry->flags & ZIP_LENGTH_AT_END)
990             && bytes_avail > zip->entry_bytes_remaining) {
991                 bytes_avail = zip->entry_bytes_remaining;
992         }
993         if (bytes_avail <= 0) {
994                 archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
995                     "Truncated ZIP file body");
996                 return (ARCHIVE_FATAL);
997         }
998
999         /*
1000          * A bug in zlib.h: stream.next_in should be marked 'const'
1001          * but isn't (the library never alters data through the
1002          * next_in pointer, only reads it).  The result: this ugly
1003          * cast to remove 'const'.
1004          */
1005         zip->stream.next_in = (Bytef *)(uintptr_t)(const void *)compressed_buff;
1006         zip->stream.avail_in = bytes_avail;
1007         zip->stream.total_in = 0;
1008         zip->stream.next_out = zip->uncompressed_buffer;
1009         zip->stream.avail_out = zip->uncompressed_buffer_size;
1010         zip->stream.total_out = 0;
1011
1012         r = inflate(&zip->stream, 0);
1013         switch (r) {
1014         case Z_OK:
1015                 break;
1016         case Z_STREAM_END:
1017                 zip->end_of_entry = 1;
1018                 break;
1019         case Z_MEM_ERROR:
1020                 archive_set_error(&a->archive, ENOMEM,
1021                     "Out of memory for ZIP decompression");
1022                 return (ARCHIVE_FATAL);
1023         default:
1024                 archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
1025                     "ZIP decompression failed (%d)", r);
1026                 return (ARCHIVE_FATAL);
1027         }
1028
1029         /* Consume as much as the compressor actually used. */
1030         bytes_avail = zip->stream.total_in;
1031         __archive_read_consume(a, bytes_avail);
1032         zip->entry_bytes_remaining -= bytes_avail;
1033         zip->entry_compressed_bytes_read += bytes_avail;
1034
1035         *size = zip->stream.total_out;
1036         zip->entry_uncompressed_bytes_read += zip->stream.total_out;
1037         *buff = zip->uncompressed_buffer;
1038
1039         if (zip->end_of_entry && (zip->entry->flags & ZIP_LENGTH_AT_END)) {
1040                 const char *p;
1041
1042                 if (NULL == (p = __archive_read_ahead(a, 16, NULL))) {
1043                         archive_set_error(&a->archive,
1044                             ARCHIVE_ERRNO_FILE_FORMAT,
1045                             "Truncated ZIP end-of-file record");
1046                         return (ARCHIVE_FATAL);
1047                 }
1048                 /* Consume the optional PK\007\010 marker. */
1049                 if (p[0] == 'P' && p[1] == 'K' && p[2] == '\007' && p[3] == '\010') {
1050                         zip->entry->crc32 = archive_le32dec(p + 4);
1051                         zip->entry->compressed_size = archive_le32dec(p + 8);
1052                         zip->entry->uncompressed_size = archive_le32dec(p + 12);
1053                         zip->unconsumed = 16;
1054                 }
1055         }
1056
1057         return (ARCHIVE_OK);
1058 }
1059 #endif
1060
1061 static int
1062 archive_read_format_zip_read_data_skip(struct archive_read *a)
1063 {
1064         struct zip *zip;
1065
1066         zip = (struct zip *)(a->format->data);
1067
1068         /* If we've already read to end of data, we're done. */
1069         if (zip->end_of_entry)
1070                 return (ARCHIVE_OK);
1071         /* If we're seeking, we're done. */
1072         if (zip->have_central_directory)
1073                 return (ARCHIVE_OK);
1074
1075         /* So we know we're streaming... */
1076         if (0 == (zip->entry->flags & ZIP_LENGTH_AT_END)) {
1077                 /* We know the compressed length, so we can just skip. */
1078                 int64_t bytes_skipped = __archive_read_consume(a,
1079                     zip->entry_bytes_remaining + zip->unconsumed);
1080                 if (bytes_skipped < 0)
1081                         return (ARCHIVE_FATAL);
1082                 zip->unconsumed = 0;
1083                 return (ARCHIVE_OK);
1084         }
1085
1086         /* We're streaming and we don't know the length. */
1087         /* If the body is compressed and we know the format, we can
1088          * find an exact end-of-entry by decompressing it. */
1089         switch (zip->entry->compression) {
1090 #ifdef HAVE_ZLIB_H
1091         case 8: /* Deflate compression. */
1092                 while (!zip->end_of_entry) {
1093                         int64_t offset = 0;
1094                         const void *buff = NULL;
1095                         size_t size = 0;
1096                         int r;
1097                         r =  zip_read_data_deflate(a, &buff, &size, &offset);
1098                         if (r != ARCHIVE_OK)
1099                                 return (r);
1100                 }
1101                 break;
1102 #endif
1103         default: /* Uncompressed or unknown. */
1104                 /* Scan for a PK\007\010 signature. */
1105                 __archive_read_consume(a, zip->unconsumed);
1106                 zip->unconsumed = 0;
1107                 for (;;) {
1108                         const char *p, *buff;
1109                         ssize_t bytes_avail;
1110                         buff = __archive_read_ahead(a, 16, &bytes_avail);
1111                         if (bytes_avail < 16) {
1112                                 archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1113                                     "Truncated ZIP file data");
1114                                 return (ARCHIVE_FATAL);
1115                         }
1116                         p = buff;
1117                         while (p <= buff + bytes_avail - 16) {
1118                                 if (p[3] == 'P') { p += 3; }
1119                                 else if (p[3] == 'K') { p += 2; }
1120                                 else if (p[3] == '\007') { p += 1; }
1121                                 else if (p[3] == '\010' && p[2] == '\007'
1122                                     && p[1] == 'K' && p[0] == 'P') {
1123                                         __archive_read_consume(a, p - buff + 16);
1124                                         return ARCHIVE_OK;
1125                                 } else { p += 4; }
1126                         }
1127                         __archive_read_consume(a, p - buff);
1128                 }
1129         }
1130         return ARCHIVE_OK;
1131 }
1132
1133 static int
1134 archive_read_format_zip_cleanup(struct archive_read *a)
1135 {
1136         struct zip *zip;
1137
1138         zip = (struct zip *)(a->format->data);
1139 #ifdef HAVE_ZLIB_H
1140         if (zip->stream_valid)
1141                 inflateEnd(&zip->stream);
1142 #endif
1143         free(zip->zip_entries);
1144         free(zip->uncompressed_buffer);
1145         archive_string_free(&(zip->extra));
1146         free(zip);
1147         (a->format->data) = NULL;
1148         return (ARCHIVE_OK);
1149 }
1150
1151 /*
1152  * The extra data is stored as a list of
1153  *      id1+size1+data1 + id2+size2+data2 ...
1154  *  triplets.  id and size are 2 bytes each.
1155  */
1156 static void
1157 process_extra(const char *p, size_t extra_length, struct zip_entry* zip_entry)
1158 {
1159         unsigned offset = 0;
1160
1161         while (offset < extra_length - 4)
1162         {
1163                 unsigned short headerid = archive_le16dec(p + offset);
1164                 unsigned short datasize = archive_le16dec(p + offset + 2);
1165                 offset += 4;
1166                 if (offset + datasize > extra_length)
1167                         break;
1168 #ifdef DEBUG
1169                 fprintf(stderr, "Header id 0x%x, length %d\n",
1170                     headerid, datasize);
1171 #endif
1172                 switch (headerid) {
1173                 case 0x0001:
1174                         /* Zip64 extended information extra field. */
1175                         if (datasize >= 8)
1176                                 zip_entry->uncompressed_size =
1177                                     archive_le64dec(p + offset);
1178                         if (datasize >= 16)
1179                                 zip_entry->compressed_size =
1180                                     archive_le64dec(p + offset + 8);
1181                         break;
1182                 case 0x5455:
1183                 {
1184                         /* Extended time field "UT". */
1185                         int flags = p[offset];
1186                         offset++;
1187                         datasize--;
1188                         /* Flag bits indicate which dates are present. */
1189                         if (flags & 0x01)
1190                         {
1191 #ifdef DEBUG
1192                                 fprintf(stderr, "mtime: %lld -> %d\n",
1193                                     (long long)zip_entry->mtime,
1194                                     archive_le32dec(p + offset));
1195 #endif
1196                                 if (datasize < 4)
1197                                         break;
1198                                 zip_entry->mtime = archive_le32dec(p + offset);
1199                                 offset += 4;
1200                                 datasize -= 4;
1201                         }
1202                         if (flags & 0x02)
1203                         {
1204                                 if (datasize < 4)
1205                                         break;
1206                                 zip_entry->atime = archive_le32dec(p + offset);
1207                                 offset += 4;
1208                                 datasize -= 4;
1209                         }
1210                         if (flags & 0x04)
1211                         {
1212                                 if (datasize < 4)
1213                                         break;
1214                                 zip_entry->ctime = archive_le32dec(p + offset);
1215                                 offset += 4;
1216                                 datasize -= 4;
1217                         }
1218                         break;
1219                 }
1220                 case 0x5855:
1221                 {
1222                         /* Info-ZIP Unix Extra Field (old version) "UX". */
1223                         if (datasize >= 8) {
1224                                 zip_entry->atime = archive_le32dec(p + offset);
1225                                 zip_entry->mtime = archive_le32dec(p + offset + 4);
1226                         }
1227                         if (datasize >= 12) {
1228                                 zip_entry->uid = archive_le16dec(p + offset + 8);
1229                                 zip_entry->gid = archive_le16dec(p + offset + 10);
1230                         }
1231                         break;
1232                 }
1233                 case 0x7855:
1234                         /* Info-ZIP Unix Extra Field (type 2) "Ux". */
1235 #ifdef DEBUG
1236                         fprintf(stderr, "uid %d gid %d\n",
1237                             archive_le16dec(p + offset),
1238                             archive_le16dec(p + offset + 2));
1239 #endif
1240                         if (datasize >= 2)
1241                                 zip_entry->uid = archive_le16dec(p + offset);
1242                         if (datasize >= 4)
1243                                 zip_entry->gid = archive_le16dec(p + offset + 2);
1244                         break;
1245                 case 0x7875:
1246                 {
1247                         /* Info-Zip Unix Extra Field (type 3) "ux". */
1248                         int uidsize = 0, gidsize = 0;
1249
1250                         if (datasize >= 1 && p[offset] == 1) {/* version=1 */
1251                                 if (datasize >= 4) {
1252                                         /* get a uid size. */
1253                                         uidsize = p[offset+1];
1254                                         if (uidsize == 2)
1255                                                 zip_entry->uid = archive_le16dec(
1256                                                      p + offset + 2);
1257                                         else if (uidsize == 4 && datasize >= 6)
1258                                                 zip_entry->uid = archive_le32dec(
1259                                                      p + offset + 2);
1260                                 }
1261                                 if (datasize >= (2 + uidsize + 3)) {
1262                                         /* get a gid size. */
1263                                         gidsize = p[offset+2+uidsize];
1264                                         if (gidsize == 2)
1265                                                 zip_entry->gid = archive_le16dec(
1266                                                     p+offset+2+uidsize+1);
1267                                         else if (gidsize == 4 &&
1268                                             datasize >= (2 + uidsize + 5))
1269                                                 zip_entry->gid = archive_le32dec(
1270                                                     p+offset+2+uidsize+1);
1271                                 }
1272                         }
1273                         break;
1274                 }
1275                 default:
1276                         break;
1277                 }
1278                 offset += datasize;
1279         }
1280 #ifdef DEBUG
1281         if (offset != extra_length)
1282         {
1283                 fprintf(stderr,
1284                     "Extra data field contents do not match reported size!\n");
1285         }
1286 #endif
1287 }