2 * Copyright (c) 2004 Tim Kientzle
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 #include "archive_platform.h"
27 __FBSDID("$FreeBSD: src/lib/libarchive/archive_read_support_format_zip.c,v 1.16 2007/12/04 06:32:12 kientzle Exp $");
42 #include "archive_entry.h"
43 #include "archive_private.h"
44 #include "archive_read_private.h"
47 /* entry_bytes_remaining is the number of bytes we expect. */
48 int64_t entry_bytes_remaining
;
51 /* These count the number of bytes actually read for the entry. */
52 int64_t entry_compressed_bytes_read
;
53 int64_t entry_uncompressed_bytes_read
;
59 const char * compression_name
;
67 /* Flags to mark progress of decompression. */
70 char end_of_entry_cleanup
;
73 ssize_t filename_length
;
75 int64_t uncompressed_size
;
76 int64_t compressed_size
;
78 unsigned char *uncompressed_buffer
;
79 size_t uncompressed_buffer_size
;
85 struct archive_string pathname
;
86 struct archive_string extra
;
90 #define ZIP_LENGTH_AT_END 8
92 struct zip_file_header
{
99 char compressed_size
[4];
100 char uncompressed_size
[4];
101 char filename_length
[2];
102 char extra_length
[2];
105 static const char *compression_names
[] = {
117 static int archive_read_format_zip_bid(struct archive_read
*);
118 static int archive_read_format_zip_cleanup(struct archive_read
*);
119 static int archive_read_format_zip_read_data(struct archive_read
*,
120 const void **, size_t *, off_t
*);
121 static int archive_read_format_zip_read_data_skip(struct archive_read
*a
);
122 static int archive_read_format_zip_read_header(struct archive_read
*,
123 struct archive_entry
*);
124 static int i2(const char *);
125 static int i4(const char *);
126 static unsigned int u2(const char *);
127 static unsigned int u4(const char *);
128 static uint64_t u8(const char *);
129 static int zip_read_data_deflate(struct archive_read
*a
, const void **buff
,
130 size_t *size
, off_t
*offset
);
131 static int zip_read_data_none(struct archive_read
*a
, const void **buff
,
132 size_t *size
, off_t
*offset
);
133 static int zip_read_file_header(struct archive_read
*a
,
134 struct archive_entry
*entry
, struct zip
*zip
);
135 static time_t zip_time(const char *);
136 static void process_extra(const void* extra
, struct zip
* zip
);
139 archive_read_support_format_zip(struct archive
*_a
)
141 struct archive_read
*a
= (struct archive_read
*)_a
;
145 zip
= (struct zip
*)malloc(sizeof(*zip
));
147 archive_set_error(&a
->archive
, ENOMEM
, "Can't allocate zip data");
148 return (ARCHIVE_FATAL
);
150 memset(zip
, 0, sizeof(*zip
));
152 r
= __archive_read_register_format(a
,
154 archive_read_format_zip_bid
,
155 archive_read_format_zip_read_header
,
156 archive_read_format_zip_read_data
,
157 archive_read_format_zip_read_data_skip
,
158 archive_read_format_zip_cleanup
);
167 archive_read_format_zip_bid(struct archive_read
*a
)
174 if (a
->archive
.archive_format
== ARCHIVE_FORMAT_ZIP
)
177 bytes_read
= (a
->decompressor
->read_ahead
)(a
, &h
, 4);
183 * Bid of 30 here is: 16 bits for "PK",
184 * next 16-bit field has four options (-2 bits).
187 if (p
[0] == 'P' && p
[1] == 'K') {
188 if ((p
[2] == '\001' && p
[3] == '\002')
189 || (p
[2] == '\003' && p
[3] == '\004')
190 || (p
[2] == '\005' && p
[3] == '\006')
191 || (p
[2] == '\007' && p
[3] == '\010'))
198 archive_read_format_zip_read_header(struct archive_read
*a
,
199 struct archive_entry
*entry
)
203 const char *signature
;
206 a
->archive
.archive_format
= ARCHIVE_FORMAT_ZIP
;
207 if (a
->archive
.archive_format_name
== NULL
)
208 a
->archive
.archive_format_name
= "ZIP";
210 zip
= (struct zip
*)(a
->format
->data
);
211 zip
->decompress_init
= 0;
212 zip
->end_of_entry
= 0;
213 zip
->end_of_entry_cleanup
= 0;
214 zip
->entry_uncompressed_bytes_read
= 0;
215 zip
->entry_compressed_bytes_read
= 0;
216 bytes_read
= (a
->decompressor
->read_ahead
)(a
, &h
, 4);
218 return (ARCHIVE_FATAL
);
220 signature
= (const char *)h
;
221 if (signature
[0] != 'P' || signature
[1] != 'K') {
222 archive_set_error(&a
->archive
, ARCHIVE_ERRNO_FILE_FORMAT
,
224 return (ARCHIVE_FATAL
);
227 if (signature
[2] == '\001' && signature
[3] == '\002') {
228 /* Beginning of central directory. */
229 return (ARCHIVE_EOF
);
232 if (signature
[2] == '\003' && signature
[3] == '\004') {
233 /* Regular file entry. */
234 return (zip_read_file_header(a
, entry
, zip
));
237 if (signature
[2] == '\005' && signature
[3] == '\006') {
238 /* End-of-archive record. */
239 return (ARCHIVE_EOF
);
242 if (signature
[2] == '\007' && signature
[3] == '\010') {
244 * We should never encounter this record here;
245 * see ZIP_LENGTH_AT_END handling below for details.
247 archive_set_error(&a
->archive
, ARCHIVE_ERRNO_MISC
,
248 "Bad ZIP file: Unexpected end-of-entry record");
249 return (ARCHIVE_FATAL
);
252 archive_set_error(&a
->archive
, ARCHIVE_ERRNO_FILE_FORMAT
,
253 "Damaged ZIP file or unsupported format variant (%d,%d)",
254 signature
[2], signature
[3]);
255 return (ARCHIVE_FATAL
);
259 zip_read_file_header(struct archive_read
*a
, struct archive_entry
*entry
,
262 const struct zip_file_header
*p
;
267 (a
->decompressor
->read_ahead
)(a
, &h
, sizeof(struct zip_file_header
));
268 if (bytes_read
< (int)sizeof(struct zip_file_header
)) {
269 archive_set_error(&a
->archive
, ARCHIVE_ERRNO_FILE_FORMAT
,
270 "Truncated ZIP file header");
271 return (ARCHIVE_FATAL
);
273 p
= (const struct zip_file_header
*)h
;
275 zip
->version
= p
->version
[0];
276 zip
->system
= p
->version
[1];
277 zip
->flags
= i2(p
->flags
);
278 zip
->compression
= i2(p
->compression
);
279 if (zip
->compression
<
280 sizeof(compression_names
)/sizeof(compression_names
[0]))
281 zip
->compression_name
= compression_names
[zip
->compression
];
283 zip
->compression_name
= "??";
284 zip
->mtime
= zip_time(p
->timedate
);
290 zip
->crc32
= i4(p
->crc32
);
291 zip
->filename_length
= i2(p
->filename_length
);
292 zip
->extra_length
= i2(p
->extra_length
);
293 zip
->uncompressed_size
= u4(p
->uncompressed_size
);
294 zip
->compressed_size
= u4(p
->compressed_size
);
296 (a
->decompressor
->consume
)(a
, sizeof(struct zip_file_header
));
299 /* Read the filename. */
300 bytes_read
= (a
->decompressor
->read_ahead
)(a
, &h
, zip
->filename_length
);
301 if (bytes_read
< zip
->filename_length
) {
302 archive_set_error(&a
->archive
, ARCHIVE_ERRNO_FILE_FORMAT
,
303 "Truncated ZIP file header");
304 return (ARCHIVE_FATAL
);
306 if (archive_string_ensure(&zip
->pathname
, zip
->filename_length
) == NULL
)
307 __archive_errx(1, "Out of memory");
308 archive_strncpy(&zip
->pathname
, (const char *)h
, zip
->filename_length
);
309 (a
->decompressor
->consume
)(a
, zip
->filename_length
);
310 archive_entry_set_pathname(entry
, zip
->pathname
.s
);
312 if (zip
->pathname
.s
[archive_strlen(&zip
->pathname
) - 1] == '/')
313 zip
->mode
= AE_IFDIR
| 0777;
315 zip
->mode
= AE_IFREG
| 0777;
317 /* Read the extra data. */
318 bytes_read
= (a
->decompressor
->read_ahead
)(a
, &h
, zip
->extra_length
);
319 if (bytes_read
< zip
->extra_length
) {
320 archive_set_error(&a
->archive
, ARCHIVE_ERRNO_FILE_FORMAT
,
321 "Truncated ZIP file header");
322 return (ARCHIVE_FATAL
);
324 process_extra(h
, zip
);
325 (a
->decompressor
->consume
)(a
, zip
->extra_length
);
327 /* Populate some additional entry fields: */
328 archive_entry_set_mode(entry
, zip
->mode
);
329 archive_entry_set_uid(entry
, zip
->uid
);
330 archive_entry_set_gid(entry
, zip
->gid
);
331 archive_entry_set_mtime(entry
, zip
->mtime
, 0);
332 archive_entry_set_ctime(entry
, zip
->ctime
, 0);
333 archive_entry_set_atime(entry
, zip
->atime
, 0);
334 archive_entry_set_size(entry
, zip
->uncompressed_size
);
336 zip
->entry_bytes_remaining
= zip
->compressed_size
;
337 zip
->entry_offset
= 0;
339 /* If there's no body, force read_data() to return EOF immediately. */
340 if (0 == (zip
->flags
& ZIP_LENGTH_AT_END
)
341 && zip
->entry_bytes_remaining
< 1)
342 zip
->end_of_entry
= 1;
344 /* Set up a more descriptive format name. */
345 sprintf(zip
->format_name
, "ZIP %d.%d (%s)",
346 zip
->version
/ 10, zip
->version
% 10,
347 zip
->compression_name
);
348 a
->archive
.archive_format_name
= zip
->format_name
;
353 /* Convert an MSDOS-style date/time into Unix-style time. */
355 zip_time(const char *p
)
360 msTime
= (0xff & (unsigned)p
[0]) + 256 * (0xff & (unsigned)p
[1]);
361 msDate
= (0xff & (unsigned)p
[2]) + 256 * (0xff & (unsigned)p
[3]);
363 memset(&ts
, 0, sizeof(ts
));
364 ts
.tm_year
= ((msDate
>> 9) & 0x7f) + 80; /* Years since 1900. */
365 ts
.tm_mon
= ((msDate
>> 5) & 0x0f) - 1; /* Month number. */
366 ts
.tm_mday
= msDate
& 0x1f; /* Day of month. */
367 ts
.tm_hour
= (msTime
>> 11) & 0x1f;
368 ts
.tm_min
= (msTime
>> 5) & 0x3f;
369 ts
.tm_sec
= (msTime
<< 1) & 0x3e;
375 archive_read_format_zip_read_data(struct archive_read
*a
,
376 const void **buff
, size_t *size
, off_t
*offset
)
381 zip
= (struct zip
*)(a
->format
->data
);
384 * If we hit end-of-entry last time, clean up and return
385 * ARCHIVE_EOF this time.
387 if (zip
->end_of_entry
) {
388 if (!zip
->end_of_entry_cleanup
) {
389 if (zip
->flags
& ZIP_LENGTH_AT_END
) {
393 (a
->decompressor
->read_ahead
)(a
, &h
, 16);
394 if (bytes_read
< 16) {
395 archive_set_error(&a
->archive
,
396 ARCHIVE_ERRNO_FILE_FORMAT
,
397 "Truncated ZIP end-of-file record");
398 return (ARCHIVE_FATAL
);
401 zip
->crc32
= i4(p
+ 4);
402 zip
->compressed_size
= u4(p
+ 8);
403 zip
->uncompressed_size
= u4(p
+ 12);
404 bytes_read
= (a
->decompressor
->consume
)(a
, 16);
407 /* Check file size, CRC against these values. */
408 if (zip
->compressed_size
!= zip
->entry_compressed_bytes_read
) {
409 archive_set_error(&a
->archive
, ARCHIVE_ERRNO_MISC
,
410 "ZIP compressed data is wrong size");
411 return (ARCHIVE_WARN
);
413 /* Size field only stores the lower 32 bits of the actual size. */
414 if ((zip
->uncompressed_size
& UINT32_MAX
)
415 != (zip
->entry_uncompressed_bytes_read
& UINT32_MAX
)) {
416 archive_set_error(&a
->archive
, ARCHIVE_ERRNO_MISC
,
417 "ZIP uncompressed data is wrong size");
418 return (ARCHIVE_WARN
);
420 /* TODO: Compute CRC. */
422 if (zip->crc32 != zip->entry_crc32_calculated) {
423 archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
424 "ZIP data CRC error");
425 return (ARCHIVE_WARN);
428 /* End-of-entry cleanup done. */
429 zip
->end_of_entry_cleanup
= 1;
431 *offset
= zip
->entry_uncompressed_bytes_read
;
434 return (ARCHIVE_EOF
);
437 switch(zip
->compression
) {
438 case 0: /* No compression. */
439 r
= zip_read_data_none(a
, buff
, size
, offset
);
441 case 8: /* Deflate compression. */
442 r
= zip_read_data_deflate(a
, buff
, size
, offset
);
444 default: /* Unsupported compression. */
448 /* Return a warning. */
449 archive_set_error(&a
->archive
, ARCHIVE_ERRNO_FILE_FORMAT
,
450 "Unsupported ZIP compression method (%s)",
451 zip
->compression_name
);
452 if (zip
->flags
& ZIP_LENGTH_AT_END
) {
454 * ZIP_LENGTH_AT_END requires us to
455 * decompress the entry in order to
456 * skip it, but we don't know this
457 * compression method, so we give up.
461 /* We know compressed size; just skip it. */
462 archive_read_format_zip_read_data_skip(a
);
471 * Read "uncompressed" data. According to the current specification,
472 * if ZIP_LENGTH_AT_END is specified, then the size fields in the
473 * initial file header are supposed to be set to zero. This would, of
474 * course, make it impossible for us to read the archive, since we
475 * couldn't determine the end of the file data. Info-ZIP seems to
476 * include the real size fields both before and after the data in this
477 * case (the CRC only appears afterwards), so this works as you would
480 * Returns ARCHIVE_OK if successful, ARCHIVE_FATAL otherwise, sets
481 * zip->end_of_entry if it consumes all of the data.
484 zip_read_data_none(struct archive_read
*a
, const void **buff
,
485 size_t *size
, off_t
*offset
)
490 zip
= (struct zip
*)(a
->format
->data
);
492 if (zip
->entry_bytes_remaining
== 0) {
495 *offset
= zip
->entry_offset
;
496 zip
->end_of_entry
= 1;
500 * Note: '1' here is a performance optimization.
501 * Recall that the decompression layer returns a count of
502 * available bytes; asking for more than that forces the
503 * decompressor to combine reads by copying data.
505 bytes_avail
= (a
->decompressor
->read_ahead
)(a
, buff
, 1);
506 if (bytes_avail
<= 0) {
507 archive_set_error(&a
->archive
, ARCHIVE_ERRNO_FILE_FORMAT
,
508 "Truncated ZIP file data");
509 return (ARCHIVE_FATAL
);
511 if (bytes_avail
> zip
->entry_bytes_remaining
)
512 bytes_avail
= zip
->entry_bytes_remaining
;
513 (a
->decompressor
->consume
)(a
, bytes_avail
);
515 *offset
= zip
->entry_offset
;
516 zip
->entry_offset
+= *size
;
517 zip
->entry_bytes_remaining
-= *size
;
518 zip
->entry_uncompressed_bytes_read
+= *size
;
519 zip
->entry_compressed_bytes_read
+= *size
;
525 zip_read_data_deflate(struct archive_read
*a
, const void **buff
,
526 size_t *size
, off_t
*offset
)
530 const void *compressed_buff
;
533 zip
= (struct zip
*)(a
->format
->data
);
535 /* If the buffer hasn't been allocated, allocate it now. */
536 if (zip
->uncompressed_buffer
== NULL
) {
537 zip
->uncompressed_buffer_size
= 32 * 1024;
538 zip
->uncompressed_buffer
539 = (unsigned char *)malloc(zip
->uncompressed_buffer_size
);
540 if (zip
->uncompressed_buffer
== NULL
) {
541 archive_set_error(&a
->archive
, ENOMEM
,
542 "No memory for ZIP decompression");
543 return (ARCHIVE_FATAL
);
547 /* If we haven't yet read any data, initialize the decompressor. */
548 if (!zip
->decompress_init
) {
549 if (zip
->stream_valid
)
550 r
= inflateReset(&zip
->stream
);
552 r
= inflateInit2(&zip
->stream
,
553 -15 /* Don't check for zlib header */);
555 archive_set_error(&a
->archive
, ARCHIVE_ERRNO_MISC
,
556 "Can't initialize ZIP decompression.");
557 return (ARCHIVE_FATAL
);
559 /* Stream structure has been set up. */
560 zip
->stream_valid
= 1;
561 /* We've initialized decompression for this stream. */
562 zip
->decompress_init
= 1;
566 * Note: '1' here is a performance optimization.
567 * Recall that the decompression layer returns a count of
568 * available bytes; asking for more than that forces the
569 * decompressor to combine reads by copying data.
571 bytes_avail
= (a
->decompressor
->read_ahead
)(a
, &compressed_buff
, 1);
572 if (bytes_avail
<= 0) {
573 archive_set_error(&a
->archive
, ARCHIVE_ERRNO_FILE_FORMAT
,
574 "Truncated ZIP file body");
575 return (ARCHIVE_FATAL
);
579 * A bug in zlib.h: stream.next_in should be marked 'const'
580 * but isn't (the library never alters data through the
581 * next_in pointer, only reads it). The result: this ugly
582 * cast to remove 'const'.
584 zip
->stream
.next_in
= (Bytef
*)(uintptr_t)(const void *)compressed_buff
;
585 zip
->stream
.avail_in
= bytes_avail
;
586 zip
->stream
.total_in
= 0;
587 zip
->stream
.next_out
= zip
->uncompressed_buffer
;
588 zip
->stream
.avail_out
= zip
->uncompressed_buffer_size
;
589 zip
->stream
.total_out
= 0;
591 r
= inflate(&zip
->stream
, 0);
596 zip
->end_of_entry
= 1;
599 archive_set_error(&a
->archive
, ENOMEM
,
600 "Out of memory for ZIP decompression");
601 return (ARCHIVE_FATAL
);
603 archive_set_error(&a
->archive
, ARCHIVE_ERRNO_MISC
,
604 "ZIP decompression failed (%d)", r
);
605 return (ARCHIVE_FATAL
);
608 /* Consume as much as the compressor actually used. */
609 bytes_avail
= zip
->stream
.total_in
;
610 (a
->decompressor
->consume
)(a
, bytes_avail
);
611 zip
->entry_bytes_remaining
-= bytes_avail
;
612 zip
->entry_compressed_bytes_read
+= bytes_avail
;
614 *offset
= zip
->entry_offset
;
615 *size
= zip
->stream
.total_out
;
616 zip
->entry_uncompressed_bytes_read
+= *size
;
617 *buff
= zip
->uncompressed_buffer
;
618 zip
->entry_offset
+= *size
;
623 zip_read_data_deflate(struct archive_read
*a
, const void **buff
,
624 size_t *size
, off_t
*offset
)
629 archive_set_error(&a
->archive
, ARCHIVE_ERRNO_MISC
,
630 "libarchive compiled without deflate support (no libz)");
631 return (ARCHIVE_FATAL
);
636 archive_read_format_zip_read_data_skip(struct archive_read
*a
)
639 const void *buff
= NULL
;
642 zip
= (struct zip
*)(a
->format
->data
);
645 * If the length is at the end, we have no choice but
646 * to decompress all the data to find the end marker.
648 if (zip
->flags
& ZIP_LENGTH_AT_END
) {
653 r
= archive_read_format_zip_read_data(a
, &buff
,
655 } while (r
== ARCHIVE_OK
);
660 * If the length is at the beginning, we can skip the
661 * compressed data much more quickly.
663 while (zip
->entry_bytes_remaining
> 0) {
664 bytes_avail
= (a
->decompressor
->read_ahead
)(a
, &buff
, 1);
665 if (bytes_avail
<= 0) {
666 archive_set_error(&a
->archive
,
667 ARCHIVE_ERRNO_FILE_FORMAT
,
668 "Truncated ZIP file body");
669 return (ARCHIVE_FATAL
);
671 if (bytes_avail
> zip
->entry_bytes_remaining
)
672 bytes_avail
= zip
->entry_bytes_remaining
;
673 (a
->decompressor
->consume
)(a
, bytes_avail
);
674 zip
->entry_bytes_remaining
-= bytes_avail
;
676 /* This entry is finished and done. */
677 zip
->end_of_entry_cleanup
= zip
->end_of_entry
= 1;
682 archive_read_format_zip_cleanup(struct archive_read
*a
)
686 zip
= (struct zip
*)(a
->format
->data
);
688 if (zip
->stream_valid
)
689 inflateEnd(&zip
->stream
);
691 free(zip
->uncompressed_buffer
);
692 archive_string_free(&(zip
->pathname
));
693 archive_string_free(&(zip
->extra
));
695 (a
->format
->data
) = NULL
;
702 return ((0xff & (int)p
[0]) + 256 * (0xff & (int)p
[1]));
709 return ((0xffff & i2(p
)) + 0x10000 * (0xffff & i2(p
+2)));
715 return ((0xff & (unsigned int)p
[0]) + 256 * (0xff & (unsigned int)p
[1]));
721 return u2(p
) + 0x10000 * u2(p
+2);
727 return u4(p
) + 0x100000000LL
* u4(p
+4);
731 * The extra data is stored as a list of
732 * id1+size1+data1 + id2+size2+data2 ...
733 * triplets. id and size are 2 bytes each.
736 process_extra(const void* extra
, struct zip
* zip
)
739 const char *p
= (const char *)extra
;
740 while (offset
< zip
->extra_length
- 4)
742 unsigned short headerid
= u2(p
+ offset
);
743 unsigned short datasize
= u2(p
+ offset
+ 2);
745 if (offset
+ datasize
> zip
->extra_length
)
748 fprintf(stderr
, "Header id 0x%04x, length %d\n",
753 /* Zip64 extended information extra field. */
755 zip
->uncompressed_size
= u8(p
+ offset
);
757 zip
->compressed_size
= u8(p
+ offset
+ 8);
761 /* Extended time field "UT". */
762 int flags
= p
[offset
];
765 /* Flag bits indicate which dates are present. */
769 fprintf(stderr
, "mtime: %lld -> %d\n",
770 (long long)zip
->mtime
, i4(p
+ offset
));
774 zip
->mtime
= i4(p
+ offset
);
782 zip
->atime
= i4(p
+ offset
);
790 zip
->ctime
= i4(p
+ offset
);
797 /* Info-ZIP Unix Extra Field (type 2) "Ux". */
799 fprintf(stderr
, "uid %d gid %d\n",
800 i2(p
+ offset
), i2(p
+ offset
+ 2));
803 zip
->uid
= i2(p
+ offset
);
805 zip
->gid
= i2(p
+ offset
+ 2);
813 if (offset
!= zip
->extra_length
)
816 "Extra data field contents do not match reported size!");