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