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