aboutsummaryrefslogtreecommitdiff
path: root/src/common/unzip.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/unzip.c')
-rw-r--r--src/common/unzip.c977
1 files changed, 527 insertions, 450 deletions
diff --git a/src/common/unzip.c b/src/common/unzip.c
index 144c5ac..b4d4258 100644
--- a/src/common/unzip.c
+++ b/src/common/unzip.c
@@ -25,6 +25,39 @@
25 * This code is based in part on 25 * This code is based in part on
26 * unzip 1.00 Copyright 1998-2003 Gilles Vollant 26 * unzip 1.00 Copyright 1998-2003 Gilles Vollant
27 * http://www.winimage.com/zLibDll" 27 * http://www.winimage.com/zLibDll"
28 *
29 *
30 * The filenames for each file in a zipfile are stored in two locations.
31 * There is one at the start of each entry, just before the compressed data,
32 * and another at the end in a 'central directory structure'.
33 *
34 * In order to catch self-extracting executables, we scan backwards from the end
35 * of the file looking for the central directory structure. The previous version
36 * of this went forewards through the local headers, but that only works for plain
37 * vanilla zip's and I don't feel like writing a special case for each of the dozen
38 * self-extracting executable stubs.
39 *
40 * This assumes that the zip file is considered to be non-corrupt/non-truncated.
41 * If it is truncated then it's not considered to be a zip and skipped.
42 *
43 * ZIP format description from appnote.iz and appnote.txt (more or less):
44 *
45 * (this is why you always need to put in the last floppy if you span disks)
46 *
47 * 0- 3 end of central dir signature 4 bytes (0x06054b50) P K ^E ^F
48 * 4- 5 number of this disk 2 bytes
49 * 6- 7 number of the disk with the
50 * start of the central directory 2 bytes
51 * 8- 9 total number of entries in
52 * the central dir on this disk 2 bytes
53 * 10-11 total number of entries in
54 * the central dir 2 bytes
55 * 12-15 size of the central directory 4 bytes
56 * 16-19 offset of start of central
57 * directory with respect to
58 * the starting disk number 4 bytes
59 * 20-21 zipfile comment length 2 bytes
60 * 22-?? zipfile comment (variable size) max length 65536 bytes
28 */ 61 */
29#include "platform.h" 62#include "platform.h"
30#include <ctype.h> 63#include <ctype.h>
@@ -49,27 +82,27 @@
49/** 82/**
50 * IO callbacks for access to the ZIP data. 83 * IO callbacks for access to the ZIP data.
51 */ 84 */
52struct EXTRACTOR_UnzipFileFuncDefs 85struct FileFuncDefs
53{ 86{
54 /** 87 /**
55 * Callback for reading 'size' bytes from the ZIP archive into buf. 88 * Callback for reading 'size' bytes from the ZIP archive into buf.
56 */ 89 */
57 uLong ( *zread_file) (voidpf opaque, void* buf, uLong size); 90 uLong (*zread_file) (voidpf opaque, void* buf, uLong size);
58 91
59 /** 92 /**
60 * Callback to obtain the current read offset in the ZIP archive. 93 * Callback to obtain the current read offset in the ZIP archive.
61 */ 94 */
62 long ( *ztell_file) (voidpf opaque); 95 long (*ztell_file) (voidpf opaque);
63 96
64 /** 97 /**
65 * Callback for seeking to a different position in the ZIP archive. 98 * Callback for seeking to a different position in the ZIP archive.
66 */ 99 */
67 long ( *zseek_file) (voidpf opaque, uLong offset, int origin); 100 long (*zseek_file) (voidpf opaque, uLong offset, int origin);
68 101
69 /** 102 /**
70 * Opaque argument to pass to all IO functions. 103 * Opaque argument to pass to all IO functions.
71 */ 104 */
72 voidpf opaque; 105 voidpf opaque;
73}; 106};
74 107
75 108
@@ -119,6 +152,11 @@ struct GlobalInfo
119 * size of the global comment of the zipfile 152 * size of the global comment of the zipfile
120 */ 153 */
121 uLong size_comment; 154 uLong size_comment;
155
156 /**
157 * offset of the global comment in the zipfile
158 */
159 uLong offset_comment;
122}; 160};
123 161
124 162
@@ -198,9 +236,9 @@ struct FileInZipReadInfo
198 uLong rest_read_uncompressed; 236 uLong rest_read_uncompressed;
199 237
200 /** 238 /**
201 * IO functions. (FIXME: where is this assigned?) 239 * IO functions.
202 */ 240 */
203 struct EXTRACTOR_UnzipFileFuncDefs z_filefunc; 241 struct FileFuncDefs z_filefunc;
204 242
205 /** 243 /**
206 * compression method (0==store) 244 * compression method (0==store)
@@ -223,7 +261,7 @@ struct EXTRACTOR_UnzipFile
223 /** 261 /**
224 * io structore of the zipfile 262 * io structore of the zipfile
225 */ 263 */
226 struct EXTRACTOR_UnzipFileFuncDefs z_filefunc; 264 struct FileFuncDefs z_filefunc;
227 265
228 /** 266 /**
229 * public global information 267 * public global information
@@ -279,7 +317,7 @@ struct EXTRACTOR_UnzipFile
279 /** 317 /**
280 * structure about the current file if we are decompressing it 318 * structure about the current file if we are decompressing it
281 */ 319 */
282 struct FileInZipReadInfo* pfile_in_zip_read; 320 struct FileInZipReadInfo *pfile_in_zip_read;
283 321
284 /** 322 /**
285 * Is the file encrypted? 323 * Is the file encrypted?
@@ -292,33 +330,46 @@ struct EXTRACTOR_UnzipFile
292 * Read a byte from a gz_stream; update next_in and avail_in. Return EOF 330 * Read a byte from a gz_stream; update next_in and avail_in. Return EOF
293 * for end of file. 331 * for end of file.
294 * IN assertion: the stream s has been sucessfully opened for reading. 332 * IN assertion: the stream s has been sucessfully opened for reading.
333 *
334 * @param ffd functions for performing IO operations
335 * @param pi where to store the byte that was read
336 * @return EXTRACTOR_UNZIP_OK on success, or EXTRACTOR_UNZIP_EOF
295 */ 337 */
296static int 338static int
297unzlocal_getByte (const struct EXTRACTOR_UnzipFileFuncDefs* pzlib_filefunc_def, 339read_byte_from_ffd (const struct FileFuncDefs *ffd,
298 int *pi) 340 int *pi)
299{ 341{
300 unsigned char c; 342 unsigned char c;
301 343
302 if (1 != ZREAD (*pzlib_filefunc_def, &c, 1)) 344 if (1 != ZREAD (*ffd, &c, 1))
303 return EXTRACTOR_UNZIP_EOF; 345 return EXTRACTOR_UNZIP_EOF;
304 *pi = (int) c; 346 *pi = (int) c;
305 return EXTRACTOR_UNZIP_OK; 347 return EXTRACTOR_UNZIP_OK;
306} 348}
307 349
308 350
351/**
352 * Read a short (2 bytes) from a gz_stream; update next_in and avail_in. Return EOF
353 * for end of file.
354 * IN assertion: the stream s has been sucessfully opened for reading.
355 *
356 * @param ffd functions for performing IO operations
357 * @param pi where to store the short that was read
358 * @return EXTRACTOR_UNZIP_OK on success, or EXTRACTOR_UNZIP_EOF
359 */
309static int 360static int
310unzlocal_getShort (const struct EXTRACTOR_UnzipFileFuncDefs* pzlib_filefunc_def, 361read_short_from_ffd (const struct FileFuncDefs *ffd,
311 uLong *pX) 362 uLong *pX)
312{ 363{
313 uLong x; 364 uLong x;
314 int i; 365 int i;
315 int err; 366 int err;
316 367
317 *pX = 0; 368 *pX = 0;
318 if (EXTRACTOR_UNZIP_OK != (err = unzlocal_getByte (pzlib_filefunc_def, &i))) 369 if (EXTRACTOR_UNZIP_OK != (err = read_byte_from_ffd (ffd, &i)))
319 return err; 370 return err;
320 x = (uLong) i; 371 x = (uLong) i;
321 if (EXTRACTOR_UNZIP_OK != (err = unzlocal_getByte (pzlib_filefunc_def, &i))) 372 if (EXTRACTOR_UNZIP_OK != (err = read_byte_from_ffd (ffd, &i)))
322 return err; 373 return err;
323 x += ((uLong) i) << 8; 374 x += ((uLong) i) << 8;
324 *pX = x; 375 *pX = x;
@@ -326,25 +377,34 @@ unzlocal_getShort (const struct EXTRACTOR_UnzipFileFuncDefs* pzlib_filefunc_def,
326} 377}
327 378
328 379
380/**
381 * Read a 'long' (4 bytes) from a gz_stream; update next_in and avail_in. Return EOF
382 * for end of file.
383 * IN assertion: the stream s has been sucessfully opened for reading.
384 *
385 * @param ffd functions for performing IO operations
386 * @param pi where to store the long that was read
387 * @return EXTRACTOR_UNZIP_OK on success, or EXTRACTOR_UNZIP_EOF
388 */
329static int 389static int
330unzlocal_getLong (const struct EXTRACTOR_UnzipFileFuncDefs* pzlib_filefunc_def, 390read_long_from_ffd (const struct FileFuncDefs *ffd,
331 uLong *pX) 391 uLong *pX)
332{ 392{
333 uLong x; 393 uLong x;
334 int i; 394 int i;
335 int err; 395 int err;
336 396
337 *pX = 0; 397 *pX = 0;
338 if (EXTRACTOR_UNZIP_OK != (err = unzlocal_getByte (pzlib_filefunc_def, &i))) 398 if (EXTRACTOR_UNZIP_OK != (err = read_byte_from_ffd (ffd, &i)))
339 return err; 399 return err;
340 x = (uLong) i; 400 x = (uLong) i;
341 if (EXTRACTOR_UNZIP_OK != (err = unzlocal_getByte (pzlib_filefunc_def, &i))) 401 if (EXTRACTOR_UNZIP_OK != (err = read_byte_from_ffd (ffd, &i)))
342 return err; 402 return err;
343 x += ((uLong) i) << 8; 403 x += ((uLong) i) << 8;
344 if (EXTRACTOR_UNZIP_OK != (err = unzlocal_getByte (pzlib_filefunc_def, &i))) 404 if (EXTRACTOR_UNZIP_OK != (err = read_byte_from_ffd (ffd, &i)))
345 return err; 405 return err;
346 x += ((uLong) i) << 16; 406 x += ((uLong) i) << 16;
347 if (EXTRACTOR_UNZIP_OK != (err = unzlocal_getByte (pzlib_filefunc_def, &i))) 407 if (EXTRACTOR_UNZIP_OK != (err = read_byte_from_ffd (ffd, &i)))
348 return err; 408 return err;
349 x += ((uLong) i) << 24; 409 x += ((uLong) i) << 24;
350 *pX = x; 410 *pX = x;
@@ -366,7 +426,7 @@ unzlocal_getLong (const struct EXTRACTOR_UnzipFileFuncDefs* pzlib_filefunc_def,
366 426
367 427
368/** 428/**
369 * Compare two filename (fileName1,fileName2). 429 * Compare two filenames (fileName1, fileName2).
370 * 430 *
371 * @param filename1 name of first file 431 * @param filename1 name of first file
372 * @param filename2 name of second file 432 * @param filename2 name of second file
@@ -394,27 +454,24 @@ EXTRACTOR_common_unzip_string_file_name_compare (const char* fileName1,
394 454
395 455
396/** 456/**
457 * Locate the central directory in the ZIP file.
397 * 458 *
459 * @param ffd IO functions
460 * @return offset of central directory, 0 on error
398 */ 461 */
399static uLong 462static uLong
400unzlocal_SearchCentralDir (const struct EXTRACTOR_UnzipFileFuncDefs* pzlib_filefunc_def) 463locate_central_directory (const struct FileFuncDefs *ffd)
401{ 464{
402 unsigned char *buf; 465 unsigned char buf[BUFREADCOMMENT + 4];
403 uLong uSizeFile; 466 uLong uSizeFile;
404 uLong uBackRead; 467 uLong uBackRead;
405 uLong uMaxBack = 0xffff; /* maximum size of global comment */ 468 uLong uMaxBack = 0xffff; /* maximum size of global comment */
406 uLong uPosFound = 0;
407 469
408 if (0 != ZSEEK (*pzlib_filefunc_def, 0, SEEK_END)) 470 if (0 != ZSEEK (*ffd, 0, SEEK_END))
409 return 0; 471 return 0;
410 uSizeFile = ZTELL (*pzlib_filefunc_def); 472 uSizeFile = ZTELL (*ffd);
411
412 if (uMaxBack > uSizeFile) 473 if (uMaxBack > uSizeFile)
413 uMaxBack = uSizeFile; 474 uMaxBack = uSizeFile;
414
415 if (NULL == (buf = malloc(BUFREADCOMMENT + 4)))
416 return 0;
417
418 uBackRead = 4; 475 uBackRead = 4;
419 while (uBackRead < uMaxBack) 476 while (uBackRead < uMaxBack)
420 { 477 {
@@ -427,156 +484,153 @@ unzlocal_SearchCentralDir (const struct EXTRACTOR_UnzipFileFuncDefs* pzlib_filef
427 else 484 else
428 uBackRead += BUFREADCOMMENT; 485 uBackRead += BUFREADCOMMENT;
429 uReadPos = uSizeFile - uBackRead; 486 uReadPos = uSizeFile - uBackRead;
430
431 uReadSize = ((BUFREADCOMMENT + 4) < (uSizeFile - uReadPos)) 487 uReadSize = ((BUFREADCOMMENT + 4) < (uSizeFile - uReadPos))
432 ? (BUFREADCOMMENT + 4) 488 ? (BUFREADCOMMENT + 4)
433 : (uSizeFile - uReadPos); 489 : (uSizeFile - uReadPos);
434 if (0 != ZSEEK (*pzlib_filefunc_def, uReadPos, SEEK_SET)) 490 if (0 != ZSEEK (*ffd, uReadPos, SEEK_SET))
435 break; 491 break;
436 492 if (ZREAD (*ffd, buf, uReadSize) != uReadSize)
437 if (ZREAD (*pzlib_filefunc_def, buf, uReadSize) != uReadSize)
438 break; 493 break;
439
440 i = (int) uReadSize - 3; 494 i = (int) uReadSize - 3;
441 while (i-- > 0) 495 while (i-- > 0)
442 if ( (0x50 == (*(buf+i))) && 496 if ( (0x50 == (*(buf+i))) &&
443 (0x4b == (*(buf+i+1))) && 497 (0x4b == (*(buf+i+1))) &&
444 (0x05 == (*(buf+i+2))) && 498 (0x05 == (*(buf+i+2))) &&
445 (0x06 == (*(buf+i+3))) ) 499 (0x06 == (*(buf+i+3))) )
446 { 500 return uReadPos + i;
447 uPosFound = uReadPos + i;
448 break;
449 }
450 if (0 != uPosFound)
451 break;
452 } 501 }
453 free (buf); 502 return 0;
454 return uPosFound;
455} 503}
456 504
457 505
458/** 506/**
459 * Translate date/time from Dos format to struct 507 * Translate date/time from Dos format to struct
460 * EXTRACTOR_UnzipDateTimeInfo (readable more easilty) 508 * EXTRACTOR_UnzipDateTimeInfo (readable more easilty)
509 *
510 * @param ulDosDate time in DOS format (input)
511 * @param ptm where to write time in readable format
461 */ 512 */
462static void 513static void
463unzlocal_DosDateToTmuDate (uLong ulDosDate, 514dos_date_to_tmu_date (uLong ulDosDate,
464 struct EXTRACTOR_UnzipDateTimeInfo* ptm) 515 struct EXTRACTOR_UnzipDateTimeInfo* ptm)
465{ 516{
466 uLong uDate; 517 uLong uDate;
467 518
468 uDate = (uLong) (ulDosDate >> 16); 519 uDate = (uLong) (ulDosDate >> 16);
469 ptm->tm_mday = (uInt) (uDate & 0x1f); 520 ptm->tm_mday = (uInt) (uDate & 0x1f);
470 ptm->tm_mon = (uInt) ((((uDate) & 0x1E0) / 0x20) - 1); 521 ptm->tm_mon = (uInt) ((((uDate) & 0x1E0) / 0x20) - 1);
471 ptm->tm_year = (uInt) (((uDate & 0x0FE00) / 0x0200) + 1980); 522 ptm->tm_year = (uInt) (((uDate & 0x0FE00) / 0x0200) + 1980);
472 ptm->tm_hour = (uInt) ((ulDosDate & 0xF800) / 0x800); 523 ptm->tm_hour = (uInt) ((ulDosDate & 0xF800) / 0x800);
473 ptm->tm_min = (uInt) ((ulDosDate & 0x7E0) / 0x20); 524 ptm->tm_min = (uInt) ((ulDosDate & 0x7E0) / 0x20);
474 ptm->tm_sec = (uInt) (2 * (ulDosDate & 0x1f)); 525 ptm->tm_sec = (uInt) (2 * (ulDosDate & 0x1f));
475} 526}
476 527
477 528
529/**
530 * Write info about the ZipFile in the *pglobal_info structure.
531 * No preparation of the structure is needed.
532 *
533 * @param file zipfile to manipulate
534 * @param pfile_info file information to initialize
535 * @param pfile_info_internal internal file information to initialize
536 * @param szFileName where to write the name of the current file
537 * @param fileNameBufferSize number of bytes available in szFileName
538 * @param extraField where to write extra data
539 * @param extraFieldBufferSize number of bytes available in extraField
540 * @param szComment where to write the comment on the current file
541 * @param commentBufferSize number of bytes available in szComment
542 * @return EXTRACTOR_UNZIP_OK if there is no problem.
543 */
478static int 544static int
479unzlocal_GetCurrentFileInfoInternal (struct EXTRACTOR_UnzipFile *s, 545get_current_file_info (struct EXTRACTOR_UnzipFile *file,
480 struct EXTRACTOR_UnzipFileInfo *pfile_info, 546 struct EXTRACTOR_UnzipFileInfo *pfile_info,
481 struct UnzipFileInfoInternal *pfile_info_internal, 547 struct UnzipFileInfoInternal *pfile_info_internal,
482 char *szFileName, 548 char *szFileName,
483 uLong fileNameBufferSize, 549 uLong fileNameBufferSize,
484 void *extraField, 550 void *extraField,
485 uLong extraFieldBufferSize, 551 uLong extraFieldBufferSize,
486 char *szComment, 552 char *szComment,
487 uLong commentBufferSize) 553 uLong commentBufferSize)
488{ 554{
489 struct EXTRACTOR_UnzipFileInfo file_info; 555 struct EXTRACTOR_UnzipFileInfo file_info;
490 struct UnzipFileInfoInternal file_info_internal; 556 struct UnzipFileInfoInternal file_info_internal;
491 int err = EXTRACTOR_UNZIP_OK;
492 uLong uMagic; 557 uLong uMagic;
493 long lSeek = 0; 558 long lSeek = 0;
494 559
495 if (s == NULL) 560 if (NULL == file)
496 return EXTRACTOR_UNZIP_PARAMERROR; 561 return EXTRACTOR_UNZIP_PARAMERROR;
497 if (0 != ZSEEK (s->z_filefunc, 562 if (0 != ZSEEK (file->z_filefunc,
498 s->pos_in_central_dir + s->byte_before_the_zipfile, 563 file->pos_in_central_dir + file->byte_before_the_zipfile,
499 SEEK_SET)) 564 SEEK_SET))
500 err = EXTRACTOR_UNZIP_ERRNO; 565 return EXTRACTOR_UNZIP_ERRNO;
501 566
502 /* we check the magic */ 567 /* we check the magic */
503 if (EXTRACTOR_UNZIP_OK == err) 568 if (EXTRACTOR_UNZIP_OK !=
504 { 569 read_long_from_ffd(&file->z_filefunc, &uMagic))
505 if (unzlocal_getLong(&s->z_filefunc, &uMagic) != EXTRACTOR_UNZIP_OK) 570 return EXTRACTOR_UNZIP_ERRNO;
506 err=EXTRACTOR_UNZIP_ERRNO; 571 if (0x02014b50 != uMagic)
507 else if (uMagic!=0x02014b50) 572 return EXTRACTOR_UNZIP_BADZIPFILE;
508 err=EXTRACTOR_UNZIP_BADZIPFILE;
509 }
510 if (unzlocal_getShort (&s->z_filefunc, &file_info.version) != EXTRACTOR_UNZIP_OK)
511 err = EXTRACTOR_UNZIP_ERRNO;
512
513 if (unzlocal_getShort(&s->z_filefunc, &file_info.version_needed) != EXTRACTOR_UNZIP_OK)
514 err=EXTRACTOR_UNZIP_ERRNO;
515
516 if (unzlocal_getShort(&s->z_filefunc, &file_info.flag) != EXTRACTOR_UNZIP_OK)
517 err=EXTRACTOR_UNZIP_ERRNO;
518
519 if (unzlocal_getShort(&s->z_filefunc, &file_info.compression_method) != EXTRACTOR_UNZIP_OK)
520 err=EXTRACTOR_UNZIP_ERRNO;
521
522 if (unzlocal_getLong(&s->z_filefunc, &file_info.dosDate) != EXTRACTOR_UNZIP_OK)
523 err=EXTRACTOR_UNZIP_ERRNO;
524
525 unzlocal_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date);
526
527 if (unzlocal_getLong(&s->z_filefunc, &file_info.crc) != EXTRACTOR_UNZIP_OK)
528 err=EXTRACTOR_UNZIP_ERRNO;
529
530 if (unzlocal_getLong(&s->z_filefunc, &file_info.compressed_size) != EXTRACTOR_UNZIP_OK)
531 err=EXTRACTOR_UNZIP_ERRNO;
532
533 if (unzlocal_getLong(&s->z_filefunc, &file_info.uncompressed_size) != EXTRACTOR_UNZIP_OK)
534 err=EXTRACTOR_UNZIP_ERRNO;
535
536 if (unzlocal_getShort(&s->z_filefunc, &file_info.size_filename) != EXTRACTOR_UNZIP_OK)
537 err=EXTRACTOR_UNZIP_ERRNO;
538
539 if (unzlocal_getShort(&s->z_filefunc, &file_info.size_file_extra) != EXTRACTOR_UNZIP_OK)
540 err=EXTRACTOR_UNZIP_ERRNO;
541
542 if (unzlocal_getShort(&s->z_filefunc, &file_info.size_file_comment) != EXTRACTOR_UNZIP_OK)
543 err=EXTRACTOR_UNZIP_ERRNO;
544
545 if (unzlocal_getShort(&s->z_filefunc, &file_info.disk_num_start) != EXTRACTOR_UNZIP_OK)
546 err=EXTRACTOR_UNZIP_ERRNO;
547
548 if (unzlocal_getShort(&s->z_filefunc, &file_info.internal_fa) != EXTRACTOR_UNZIP_OK)
549 err=EXTRACTOR_UNZIP_ERRNO;
550
551 if (unzlocal_getLong(&s->z_filefunc, &file_info.external_fa) != EXTRACTOR_UNZIP_OK)
552 err=EXTRACTOR_UNZIP_ERRNO;
553 573
554 if (unzlocal_getLong (&s->z_filefunc, 574 if ( (EXTRACTOR_UNZIP_OK !=
555 &file_info_internal.offset_curfile) != EXTRACTOR_UNZIP_OK) 575 read_short_from_ffd (&file->z_filefunc, &file_info.version)) ||
556 err = EXTRACTOR_UNZIP_ERRNO; 576 (EXTRACTOR_UNZIP_OK !=
577 read_short_from_ffd (&file->z_filefunc, &file_info.version_needed)) ||
578 (EXTRACTOR_UNZIP_OK !=
579 read_short_from_ffd (&file->z_filefunc, &file_info.flag)) ||
580 (EXTRACTOR_UNZIP_OK !=
581 read_short_from_ffd (&file->z_filefunc, &file_info.compression_method)) ||
582 (EXTRACTOR_UNZIP_OK !=
583 read_long_from_ffd (&file->z_filefunc, &file_info.dosDate)) )
584 return EXTRACTOR_UNZIP_ERRNO;
585 dos_date_to_tmu_date (file_info.dosDate,
586 &file_info.tmu_date);
587 if ( (EXTRACTOR_UNZIP_OK !=
588 read_long_from_ffd(&file->z_filefunc, &file_info.crc)) ||
589 (EXTRACTOR_UNZIP_OK !=
590 read_long_from_ffd(&file->z_filefunc, &file_info.compressed_size)) ||
591 (EXTRACTOR_UNZIP_OK !=
592 read_long_from_ffd(&file->z_filefunc, &file_info.uncompressed_size)) ||
593 (EXTRACTOR_UNZIP_OK !=
594 read_short_from_ffd(&file->z_filefunc, &file_info.size_filename)) ||
595 (EXTRACTOR_UNZIP_OK !=
596 read_short_from_ffd(&file->z_filefunc, &file_info.size_file_extra)) ||
597 (EXTRACTOR_UNZIP_OK !=
598 read_short_from_ffd(&file->z_filefunc, &file_info.size_file_comment)) ||
599 (EXTRACTOR_UNZIP_OK !=
600 read_short_from_ffd(&file->z_filefunc, &file_info.disk_num_start)) ||
601 (EXTRACTOR_UNZIP_OK !=
602 read_short_from_ffd(&file->z_filefunc, &file_info.internal_fa)) ||
603 (EXTRACTOR_UNZIP_OK !=
604 read_long_from_ffd(&file->z_filefunc, &file_info.external_fa)) ||
605 (EXTRACTOR_UNZIP_OK !=
606 read_long_from_ffd (&file->z_filefunc,
607 &file_info_internal.offset_curfile)) )
608 return EXTRACTOR_UNZIP_ERRNO;
557 609
558 lSeek += file_info.size_filename; 610 lSeek += file_info.size_filename;
559 if ((err==EXTRACTOR_UNZIP_OK) && (szFileName!=NULL)) 611 if (NULL != szFileName)
560 { 612 {
561 uLong uSizeRead; 613 uLong uSizeRead;
614
562 if (file_info.size_filename < fileNameBufferSize) 615 if (file_info.size_filename < fileNameBufferSize)
563 { 616 {
564 *(szFileName+file_info.size_filename) = '\0'; 617 *(szFileName + file_info.size_filename) = '\0';
565 uSizeRead = file_info.size_filename; 618 uSizeRead = file_info.size_filename;
566 } 619 }
567 else 620 else
568 uSizeRead = fileNameBufferSize; 621 uSizeRead = fileNameBufferSize;
569 622
570 if ((file_info.size_filename > 0) && (fileNameBufferSize > 0)) 623 if ( (file_info.size_filename > 0) &&
571 if (ZREAD(s->z_filefunc, szFileName, uSizeRead) != uSizeRead) 624 (fileNameBufferSize > 0) )
572 err = EXTRACTOR_UNZIP_ERRNO; 625 if (ZREAD(file->z_filefunc, szFileName, uSizeRead) != uSizeRead)
626 return EXTRACTOR_UNZIP_ERRNO;
573 lSeek -= uSizeRead; 627 lSeek -= uSizeRead;
574 } 628 }
575 629
576 630 if (NULL != extraField)
577 if ((err==EXTRACTOR_UNZIP_OK) && (extraField!=NULL))
578 { 631 {
579 uLong uSizeRead; 632 uLong uSizeRead;
633
580 if (file_info.size_file_extra<extraFieldBufferSize) 634 if (file_info.size_file_extra<extraFieldBufferSize)
581 uSizeRead = file_info.size_file_extra; 635 uSizeRead = file_info.size_file_extra;
582 else 636 else
@@ -584,53 +638,55 @@ unzlocal_GetCurrentFileInfoInternal (struct EXTRACTOR_UnzipFile *s,
584 638
585 if (0 != lSeek) 639 if (0 != lSeek)
586 { 640 {
587 if (0 == ZSEEK (s->z_filefunc, lSeek, SEEK_CUR)) 641 if (0 == ZSEEK (file->z_filefunc, lSeek, SEEK_CUR))
588 lSeek = 0; 642 lSeek = 0;
589 else 643 else
590 err = EXTRACTOR_UNZIP_ERRNO; 644 return EXTRACTOR_UNZIP_ERRNO;
591 } 645 }
592 if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0)) 646 if ( (file_info.size_file_extra > 0) &&
593 if (ZREAD(s->z_filefunc, extraField,uSizeRead)!=uSizeRead) 647 (extraFieldBufferSize > 0) &&
594 err=EXTRACTOR_UNZIP_ERRNO; 648 (ZREAD (file->z_filefunc,
649 extraField,
650 uSizeRead) != uSizeRead) )
651 return EXTRACTOR_UNZIP_ERRNO;
595 lSeek += file_info.size_file_extra - uSizeRead; 652 lSeek += file_info.size_file_extra - uSizeRead;
596 } 653 }
597 else 654 else
598 lSeek+=file_info.size_file_extra; 655 lSeek += file_info.size_file_extra;
599
600 656
601 if ((err==EXTRACTOR_UNZIP_OK) && (szComment!=NULL)) 657 if (NULL != szComment)
602 { 658 {
603 uLong uSizeRead ; 659 uLong uSizeRead;
604 if (file_info.size_file_comment<commentBufferSize) 660
661 if (file_info.size_file_comment < commentBufferSize)
605 { 662 {
606 *(szComment+file_info.size_file_comment)='\0'; 663 *(szComment+file_info.size_file_comment) = '\0';
607 uSizeRead = file_info.size_file_comment; 664 uSizeRead = file_info.size_file_comment;
608 } 665 }
609 else 666 else
610 uSizeRead = commentBufferSize; 667 uSizeRead = commentBufferSize;
611 668
612 if (lSeek!=0) 669 if (0 != lSeek)
613 { 670 {
614 if (ZSEEK(s->z_filefunc, lSeek, SEEK_CUR)==0) 671 if (0 == ZSEEK (file->z_filefunc, lSeek, SEEK_CUR))
615 lSeek=0; 672 lSeek = 0;
616 else 673 else
617 err=EXTRACTOR_UNZIP_ERRNO; 674 return EXTRACTOR_UNZIP_ERRNO;
618 } 675 }
619 if ((file_info.size_file_comment>0) && (commentBufferSize>0)) 676 if ( (file_info.size_file_comment > 0) &&
620 if (ZREAD(s->z_filefunc, szComment,uSizeRead)!=uSizeRead) 677 (commentBufferSize > 0) &&
621 err=EXTRACTOR_UNZIP_ERRNO; 678 (ZREAD (file->z_filefunc, szComment, uSizeRead) != uSizeRead) )
622 lSeek+=file_info.size_file_comment - uSizeRead; 679 return EXTRACTOR_UNZIP_ERRNO;
680 lSeek += file_info.size_file_comment - uSizeRead;
623 } 681 }
624 else 682 else
625 lSeek+=file_info.size_file_comment; 683 lSeek += file_info.size_file_comment;
626 684
627 if ((err==EXTRACTOR_UNZIP_OK) && (pfile_info!=NULL)) 685 if (NULL != pfile_info)
628 *pfile_info=file_info; 686 *pfile_info = file_info;
629 687 if (NULL != pfile_info_internal)
630 if ((err==EXTRACTOR_UNZIP_OK) && (pfile_info_internal!=NULL)) 688 *pfile_info_internal = file_info_internal;
631 *pfile_info_internal=file_info_internal; 689 return EXTRACTOR_UNZIP_OK;
632
633 return err;
634} 690}
635 691
636 692
@@ -649,11 +705,11 @@ EXTRACTOR_common_unzip_go_to_first_file (struct EXTRACTOR_UnzipFile *file)
649 return EXTRACTOR_UNZIP_PARAMERROR; 705 return EXTRACTOR_UNZIP_PARAMERROR;
650 file->pos_in_central_dir = file->offset_central_dir; 706 file->pos_in_central_dir = file->offset_central_dir;
651 file->num_file = 0; 707 file->num_file = 0;
652 err = unzlocal_GetCurrentFileInfoInternal (file, 708 err = get_current_file_info (file,
653 &file->cur_file_info, 709 &file->cur_file_info,
654 &file->cur_file_info_internal, 710 &file->cur_file_info_internal,
655 NULL, 0, NULL, 0, NULL, 0); 711 NULL, 0, NULL, 0, NULL, 0);
656 file->current_file_ok = (err == EXTRACTOR_UNZIP_OK); 712 file->current_file_ok = (EXTRACTOR_UNZIP_OK == err);
657 return err; 713 return err;
658} 714}
659 715
@@ -661,14 +717,14 @@ EXTRACTOR_common_unzip_go_to_first_file (struct EXTRACTOR_UnzipFile *file)
661/** 717/**
662 * Open a Zip file. 718 * Open a Zip file.
663 * 719 *
664 * @param pzlib_filefunc_def IO functions 720 * @param ffd IO functions
665 * @return NULL on error 721 * @return NULL on error
666 */ 722 */
667static struct EXTRACTOR_UnzipFile * 723static struct EXTRACTOR_UnzipFile *
668EXTRACTOR_common_unzip_open2 (struct EXTRACTOR_UnzipFileFuncDefs *pzlib_filefunc_def) 724unzip_open_using_ffd (struct FileFuncDefs *ffd)
669{ 725{
670 struct EXTRACTOR_UnzipFile us; 726 struct EXTRACTOR_UnzipFile us;
671 struct EXTRACTOR_UnzipFile *s; 727 struct EXTRACTOR_UnzipFile *file;
672 uLong central_pos; 728 uLong central_pos;
673 uLong uL; 729 uLong uL;
674 uLong number_disk; /* number of the current dist, used for 730 uLong number_disk; /* number of the current dist, used for
@@ -678,78 +734,76 @@ EXTRACTOR_common_unzip_open2 (struct EXTRACTOR_UnzipFileFuncDefs *pzlib_filefunc
678 uLong number_entry_CD; /* total number of entries in 734 uLong number_entry_CD; /* total number of entries in
679 the central dir 735 the central dir
680 (same than number_entry on nospan) */ 736 (same than number_entry on nospan) */
681
682 int err = EXTRACTOR_UNZIP_OK;
683 737
684 memset (&us, 0, sizeof(us)); 738 memset (&us, 0, sizeof(us));
685 us.z_filefunc = *pzlib_filefunc_def; 739 us.z_filefunc = *ffd;
686 740 central_pos = locate_central_directory (&us.z_filefunc);
687 central_pos = unzlocal_SearchCentralDir (&us.z_filefunc); 741 if (0 == central_pos)
688 if (central_pos==0) 742 return NULL;
689 err=EXTRACTOR_UNZIP_ERRNO; 743 if (0 != ZSEEK (us.z_filefunc,
690 744 central_pos, SEEK_SET))
691 if (ZSEEK(us.z_filefunc, 745 return NULL;
692 central_pos, SEEK_SET)!=0)
693 err=EXTRACTOR_UNZIP_ERRNO;
694 746
695 /* the signature, already checked */ 747 /* the signature, already checked */
696 if (unzlocal_getLong(&us.z_filefunc, &uL)!=EXTRACTOR_UNZIP_OK) 748 if (EXTRACTOR_UNZIP_OK !=
697 err=EXTRACTOR_UNZIP_ERRNO; 749 read_long_from_ffd (&us.z_filefunc, &uL))
750 return NULL;
698 751
699 /* number of this disk */ 752 /* number of this disk */
700 if (unzlocal_getShort(&us.z_filefunc, &number_disk)!=EXTRACTOR_UNZIP_OK) 753 if (EXTRACTOR_UNZIP_OK !=
701 err=EXTRACTOR_UNZIP_ERRNO; 754 read_short_from_ffd (&us.z_filefunc, &number_disk))
755 return NULL;
702 756
703 /* number of the disk with the start of the central directory */ 757 /* number of the disk with the start of the central directory */
704 if (unzlocal_getShort(&us.z_filefunc, &number_disk_with_CD)!=EXTRACTOR_UNZIP_OK) 758 if (EXTRACTOR_UNZIP_OK !=
705 err=EXTRACTOR_UNZIP_ERRNO; 759 read_short_from_ffd (&us.z_filefunc, &number_disk_with_CD))
760 return NULL;
706 761
707 /* total number of entries in the central dir on this disk */ 762 /* total number of entries in the central dir on this disk */
708 if (unzlocal_getShort(&us.z_filefunc, &us.gi.number_entry)!=EXTRACTOR_UNZIP_OK) 763 if (EXTRACTOR_UNZIP_OK !=
709 err=EXTRACTOR_UNZIP_ERRNO; 764 read_short_from_ffd (&us.z_filefunc, &us.gi.number_entry))
765 return NULL;
710 766
711 /* total number of entries in the central dir */ 767 /* total number of entries in the central dir */
712 if (unzlocal_getShort(&us.z_filefunc, &number_entry_CD)!=EXTRACTOR_UNZIP_OK) 768 if (EXTRACTOR_UNZIP_OK !=
713 err=EXTRACTOR_UNZIP_ERRNO; 769 read_short_from_ffd (&us.z_filefunc, &number_entry_CD))
770 return NULL;
714 771
715 if ((number_entry_CD!=us.gi.number_entry) || 772 if ( (number_entry_CD != us.gi.number_entry) ||
716 (number_disk_with_CD!=0) || 773 (0 != number_disk_with_CD) ||
717 (number_disk!=0)) 774 (0 != number_disk) )
718 err=EXTRACTOR_UNZIP_BADZIPFILE; 775 return NULL;
719 776
720 /* size of the central directory */ 777 /* size of the central directory */
721 if (unzlocal_getLong(&us.z_filefunc, &us.size_central_dir)!=EXTRACTOR_UNZIP_OK) 778 if (EXTRACTOR_UNZIP_OK !=
722 err=EXTRACTOR_UNZIP_ERRNO; 779 read_long_from_ffd (&us.z_filefunc, &us.size_central_dir))
780 return NULL;
723 781
724 /* offset of start of central directory with respect to the 782 /* offset of start of central directory with respect to the
725 starting disk number */ 783 starting disk number */
726 if (unzlocal_getLong(&us.z_filefunc, &us.offset_central_dir)!=EXTRACTOR_UNZIP_OK) 784 if (EXTRACTOR_UNZIP_OK !=
727 err=EXTRACTOR_UNZIP_ERRNO; 785 read_long_from_ffd (&us.z_filefunc, &us.offset_central_dir))
786 return NULL;
728 787
729 /* zipfile comment length */ 788 /* zipfile comment length */
730 if (unzlocal_getShort(&us.z_filefunc, &us.gi.size_comment)!=EXTRACTOR_UNZIP_OK) 789 if (EXTRACTOR_UNZIP_OK !=
731 err=EXTRACTOR_UNZIP_ERRNO; 790 read_short_from_ffd (&us.z_filefunc, &us.gi.size_comment))
732 791 return NULL;
733 if ((central_pos<us.offset_central_dir+us.size_central_dir) && 792 us.gi.offset_comment = ZTELL (us.z_filefunc);
734 (err==EXTRACTOR_UNZIP_OK)) 793 if ((central_pos < us.offset_central_dir + us.size_central_dir))
735 err=EXTRACTOR_UNZIP_BADZIPFILE; 794 return NULL;
736 795
737 if (err!=EXTRACTOR_UNZIP_OK)
738 {
739 return NULL;
740 }
741
742 us.byte_before_the_zipfile = central_pos - 796 us.byte_before_the_zipfile = central_pos -
743 (us.offset_central_dir+us.size_central_dir); 797 (us.offset_central_dir + us.size_central_dir);
744 us.central_pos = central_pos; 798 us.central_pos = central_pos;
745 us.pfile_in_zip_read = NULL; 799 us.pfile_in_zip_read = NULL;
746 us.encrypted = 0; 800 us.encrypted = 0;
747 801
748 if (NULL == (s = malloc (sizeof(struct EXTRACTOR_UnzipFile)))) 802 if (NULL == (file = malloc (sizeof(struct EXTRACTOR_UnzipFile))))
749 return NULL; 803 return NULL;
750 *s=us; 804 *file = us;
751 EXTRACTOR_common_unzip_go_to_first_file(s); 805 EXTRACTOR_common_unzip_go_to_first_file (file);
752 return s; 806 return file;
753} 807}
754 808
755 809
@@ -759,48 +813,32 @@ EXTRACTOR_common_unzip_open2 (struct EXTRACTOR_UnzipFileFuncDefs *pzlib_filefunc
759 * @return EXTRACTOR_UNZIP_CRCERROR if all the file was read but the CRC is not good 813 * @return EXTRACTOR_UNZIP_CRCERROR if all the file was read but the CRC is not good
760 */ 814 */
761int 815int
762EXTRACTOR_common_unzip_close_current_file (struct EXTRACTOR_UnzipFile * file) 816EXTRACTOR_common_unzip_close_current_file (struct EXTRACTOR_UnzipFile *file)
763{ 817{
764 int err=EXTRACTOR_UNZIP_OK; 818 struct FileInZipReadInfo* pfile_in_zip_read_info;
765 819 int err = EXTRACTOR_UNZIP_OK;
766 struct EXTRACTOR_UnzipFile* s; 820
767 struct FileInZipReadInfo* pfile_in_zip_read_info; 821 if (NULL == file)
768 if (file==NULL) 822 return EXTRACTOR_UNZIP_PARAMERROR;
769 return EXTRACTOR_UNZIP_PARAMERROR; 823 if (NULL == (pfile_in_zip_read_info = file->pfile_in_zip_read))
770 s=(struct EXTRACTOR_UnzipFile*)file; 824 return EXTRACTOR_UNZIP_PARAMERROR;
771 pfile_in_zip_read_info=s->pfile_in_zip_read; 825 if ( (0 == pfile_in_zip_read_info->rest_read_uncompressed) &&
772 826 (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait) )
773 if (pfile_in_zip_read_info==NULL) 827 err = EXTRACTOR_UNZIP_CRCERROR;
774 return EXTRACTOR_UNZIP_PARAMERROR; 828 if (NULL != pfile_in_zip_read_info->read_buffer)
775 829 free (pfile_in_zip_read_info->read_buffer);
776 830 pfile_in_zip_read_info->read_buffer = NULL;
777 if (pfile_in_zip_read_info->rest_read_uncompressed == 0) 831 if (pfile_in_zip_read_info->stream_initialised)
778 { 832 inflateEnd (&pfile_in_zip_read_info->stream);
779 if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait) 833 pfile_in_zip_read_info->stream_initialised = 0;
780 err=EXTRACTOR_UNZIP_CRCERROR; 834 free (pfile_in_zip_read_info);
781 } 835 file->pfile_in_zip_read = NULL;
782 836 return err;
783
784 if (NULL != pfile_in_zip_read_info->read_buffer)
785 free(pfile_in_zip_read_info->read_buffer);
786 pfile_in_zip_read_info->read_buffer = NULL;
787 if (pfile_in_zip_read_info->stream_initialised)
788 inflateEnd(&pfile_in_zip_read_info->stream);
789
790 pfile_in_zip_read_info->stream_initialised = 0;
791 free(pfile_in_zip_read_info);
792
793 s->pfile_in_zip_read=NULL;
794
795 return err;
796} 837}
797 838
798 839
799/** 840/**
800 * Close a ZipFile. If there is files inside the .Zip opened with 841 * Close a ZipFile.
801 * EXTRACTOR_common_unzip_open_current_file, these files MUST be
802 * closed with EXTRACTOR_common_unzip_close_current_file before
803 * calling EXTRACTOR_common_unzip_close.
804 * 842 *
805 * @param file zip file to close 843 * @param file zip file to close
806 * @return EXTRACTOR_UNZIP_OK if there is no problem. 844 * @return EXTRACTOR_UNZIP_OK if there is no problem.
@@ -808,17 +846,40 @@ EXTRACTOR_common_unzip_close_current_file (struct EXTRACTOR_UnzipFile * file)
808int 846int
809EXTRACTOR_common_unzip_close (struct EXTRACTOR_UnzipFile *file) 847EXTRACTOR_common_unzip_close (struct EXTRACTOR_UnzipFile *file)
810{ 848{
811 struct EXTRACTOR_UnzipFile* s; 849 if (NULL == file)
812
813 if (file==NULL)
814 return EXTRACTOR_UNZIP_PARAMERROR; 850 return EXTRACTOR_UNZIP_PARAMERROR;
815 s=(struct EXTRACTOR_UnzipFile*)file; 851 if (NULL != file->pfile_in_zip_read)
816 852 EXTRACTOR_common_unzip_close_current_file (file);
817 if (s->pfile_in_zip_read!=NULL) 853 free (file);
818 EXTRACTOR_common_unzip_close_current_file(file); 854 return EXTRACTOR_UNZIP_OK;
855}
856
819 857
820 free(s); 858/**
821 return EXTRACTOR_UNZIP_OK; 859 * Obtain the global comment from a ZIP file.
860 *
861 * @param file unzip file to inspect
862 * @param comment where to copy the comment
863 * @param comment_len maximum number of bytes available in comment
864 * @return EXTRACTOR_UNZIP_OK on success
865 */
866int
867EXTRACTOR_common_unzip_get_global_comment (struct EXTRACTOR_UnzipFile *file,
868 char *comment,
869 size_t comment_len)
870{
871 if (NULL == file)
872 return EXTRACTOR_UNZIP_PARAMERROR;
873 if (comment_len > file->gi.size_comment)
874 comment_len = file->gi.size_comment + 1;
875 if (0 !=
876 ZSEEK (file->z_filefunc, file->gi.offset_comment, SEEK_SET))
877 return EXTRACTOR_UNZIP_ERRNO;
878 if (comment_len - 1 !=
879 ZREAD (file->z_filefunc, comment, comment_len - 1))
880 return EXTRACTOR_UNZIP_ERRNO;
881 comment[comment_len - 1] = '\0';
882 return EXTRACTOR_UNZIP_OK;
822} 883}
823 884
824 885
@@ -827,6 +888,7 @@ EXTRACTOR_common_unzip_close (struct EXTRACTOR_UnzipFile *file)
827 * No preparation of the structure is needed. 888 * No preparation of the structure is needed.
828 * 889 *
829 * @param file zipfile to manipulate 890 * @param file zipfile to manipulate
891 * @param pfile_info file information to initialize
830 * @param szFileName where to write the name of the current file 892 * @param szFileName where to write the name of the current file
831 * @param fileNameBufferSize number of bytes available in szFileName 893 * @param fileNameBufferSize number of bytes available in szFileName
832 * @param extraField where to write extra data 894 * @param extraField where to write extra data
@@ -845,10 +907,10 @@ EXTRACTOR_common_unzip_get_current_file_info (struct EXTRACTOR_UnzipFile * file,
845 char *szComment, 907 char *szComment,
846 uLong commentBufferSize) 908 uLong commentBufferSize)
847{ 909{
848 return unzlocal_GetCurrentFileInfoInternal(file,pfile_info,NULL, 910 return get_current_file_info (file, pfile_info, NULL,
849 szFileName,fileNameBufferSize, 911 szFileName, fileNameBufferSize,
850 extraField,extraFieldBufferSize, 912 extraField, extraFieldBufferSize,
851 szComment,commentBufferSize); 913 szComment, commentBufferSize);
852} 914}
853 915
854 916
@@ -860,27 +922,25 @@ EXTRACTOR_common_unzip_get_current_file_info (struct EXTRACTOR_UnzipFile * file,
860 * EXTRACTOR_UNZIP_END_OF_LIST_OF_FILE if the actual file was the latest. 922 * EXTRACTOR_UNZIP_END_OF_LIST_OF_FILE if the actual file was the latest.
861 */ 923 */
862int 924int
863EXTRACTOR_common_unzip_go_to_next_file (struct EXTRACTOR_UnzipFile * file) 925EXTRACTOR_common_unzip_go_to_next_file (struct EXTRACTOR_UnzipFile *file)
864{ 926{
865 struct EXTRACTOR_UnzipFile* s; 927 int err;
866 int err; 928
867 929 if (NULL == file)
868 if (file==NULL) 930 return EXTRACTOR_UNZIP_PARAMERROR;
869 return EXTRACTOR_UNZIP_PARAMERROR; 931 if (! file->current_file_ok)
870 s=(struct EXTRACTOR_UnzipFile*)file; 932 return EXTRACTOR_UNZIP_END_OF_LIST_OF_FILE;
871 if (!s->current_file_ok) 933 if (file->num_file + 1 == file->gi.number_entry)
872 return EXTRACTOR_UNZIP_END_OF_LIST_OF_FILE; 934 return EXTRACTOR_UNZIP_END_OF_LIST_OF_FILE;
873 if (s->num_file+1==s->gi.number_entry) 935 file->pos_in_central_dir += SIZECENTRALDIRITEM + file->cur_file_info.size_filename +
874 return EXTRACTOR_UNZIP_END_OF_LIST_OF_FILE; 936 file->cur_file_info.size_file_extra + file->cur_file_info.size_file_comment;
875 937 file->num_file++;
876 s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename + 938 err = get_current_file_info (file,
877 s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ; 939 &file->cur_file_info,
878 s->num_file++; 940 &file->cur_file_info_internal,
879 err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, 941 NULL, 0, NULL, 0, NULL, 0);
880 &s->cur_file_info_internal, 942 file->current_file_ok = (EXTRACTOR_UNZIP_OK == err);
881 NULL,0,NULL,0,NULL,0); 943 return err;
882 s->current_file_ok = (err == EXTRACTOR_UNZIP_OK);
883 return err;
884} 944}
885 945
886 946
@@ -925,20 +985,20 @@ EXTRACTOR_common_unzip_go_find_local_file (struct EXTRACTOR_UnzipFile *file,
925 985
926 while (EXTRACTOR_UNZIP_OK == err) 986 while (EXTRACTOR_UNZIP_OK == err)
927 { 987 {
928 char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1]; 988 char szCurrentFileName[UNZ_MAXFILENAMEINZIP + 1];
929 989
930 err = EXTRACTOR_common_unzip_get_current_file_info (file, NULL, 990 if (EXTRACTOR_UNZIP_OK !=
931 szCurrentFileName, sizeof (szCurrentFileName) - 1, 991 (err = EXTRACTOR_common_unzip_get_current_file_info (file, NULL,
932 NULL, 0, NULL, 0); 992 szCurrentFileName,
933 if (EXTRACTOR_UNZIP_OK == err) 993 sizeof (szCurrentFileName) - 1,
934 { 994 NULL, 0, NULL, 0)))
935 if (0 == 995 break;
936 EXTRACTOR_common_unzip_string_file_name_compare (szCurrentFileName, 996 if (0 ==
937 szFileName, 997 EXTRACTOR_common_unzip_string_file_name_compare (szCurrentFileName,
938 iCaseSensitivity)) 998 szFileName,
939 return EXTRACTOR_UNZIP_OK; 999 iCaseSensitivity))
940 err = EXTRACTOR_common_unzip_go_to_next_file (file); 1000 return EXTRACTOR_UNZIP_OK;
941 } 1001 err = EXTRACTOR_common_unzip_go_to_next_file (file);
942 } 1002 }
943 1003
944 /* We failed, so restore the state of the 'current file' to where we 1004 /* We failed, so restore the state of the 'current file' to where we
@@ -969,7 +1029,7 @@ EXTRACTOR_common_unzip_read_current_file (struct EXTRACTOR_UnzipFile *file,
969{ 1029{
970 int err = EXTRACTOR_UNZIP_OK; 1030 int err = EXTRACTOR_UNZIP_OK;
971 uInt iRead = 0; 1031 uInt iRead = 0;
972 struct FileInZipReadInfo* pfile_in_zip_read_info; 1032 struct FileInZipReadInfo *pfile_in_zip_read_info;
973 1033
974 if (NULL == file) 1034 if (NULL == file)
975 return EXTRACTOR_UNZIP_PARAMERROR; 1035 return EXTRACTOR_UNZIP_PARAMERROR;
@@ -980,7 +1040,7 @@ EXTRACTOR_common_unzip_read_current_file (struct EXTRACTOR_UnzipFile *file,
980 if (0 == len) 1040 if (0 == len)
981 return 0; 1041 return 0;
982 1042
983 pfile_in_zip_read_info->stream.next_out = (Bytef*) buf; 1043 pfile_in_zip_read_info->stream.next_out = (Bytef *) buf;
984 pfile_in_zip_read_info->stream.avail_out = (uInt) len; 1044 pfile_in_zip_read_info->stream.avail_out = (uInt) len;
985 if (len > pfile_in_zip_read_info->rest_read_uncompressed) 1045 if (len > pfile_in_zip_read_info->rest_read_uncompressed)
986 pfile_in_zip_read_info->stream.avail_out = 1046 pfile_in_zip_read_info->stream.avail_out =
@@ -989,14 +1049,14 @@ EXTRACTOR_common_unzip_read_current_file (struct EXTRACTOR_UnzipFile *file,
989 while (pfile_in_zip_read_info->stream.avail_out > 0) 1049 while (pfile_in_zip_read_info->stream.avail_out > 0)
990 { 1050 {
991 if ( (0 == pfile_in_zip_read_info->stream.avail_in) && 1051 if ( (0 == pfile_in_zip_read_info->stream.avail_in) &&
992 (pfile_in_zip_read_info->rest_read_compressed>0) ) 1052 (pfile_in_zip_read_info->rest_read_compressed > 0) )
993 { 1053 {
994 uInt uReadThis = UNZ_BUFSIZE; 1054 uInt uReadThis = UNZ_BUFSIZE;
995 if (pfile_in_zip_read_info->rest_read_compressed<uReadThis) 1055 if (pfile_in_zip_read_info->rest_read_compressed<uReadThis)
996 uReadThis = (uInt) pfile_in_zip_read_info->rest_read_compressed; 1056 uReadThis = (uInt) pfile_in_zip_read_info->rest_read_compressed;
997 if (0 == uReadThis) 1057 if (0 == uReadThis)
998 return EXTRACTOR_UNZIP_EOF; 1058 return EXTRACTOR_UNZIP_EOF;
999 if (0 != 1059 if (0 !=
1000 ZSEEK (pfile_in_zip_read_info->z_filefunc, 1060 ZSEEK (pfile_in_zip_read_info->z_filefunc,
1001 pfile_in_zip_read_info->pos_in_zipfile + 1061 pfile_in_zip_read_info->pos_in_zipfile +
1002 pfile_in_zip_read_info->byte_before_the_zipfile, 1062 pfile_in_zip_read_info->byte_before_the_zipfile,
@@ -1008,78 +1068,75 @@ EXTRACTOR_common_unzip_read_current_file (struct EXTRACTOR_UnzipFile *file,
1008 return EXTRACTOR_UNZIP_ERRNO; 1068 return EXTRACTOR_UNZIP_ERRNO;
1009 1069
1010 pfile_in_zip_read_info->pos_in_zipfile += uReadThis; 1070 pfile_in_zip_read_info->pos_in_zipfile += uReadThis;
1011 pfile_in_zip_read_info->rest_read_compressed-=uReadThis; 1071 pfile_in_zip_read_info->rest_read_compressed -= uReadThis;
1012 pfile_in_zip_read_info->stream.next_in = 1072 pfile_in_zip_read_info->stream.next_in =
1013 (Bytef*)pfile_in_zip_read_info->read_buffer; 1073 (Bytef *) pfile_in_zip_read_info->read_buffer;
1014 pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis; 1074 pfile_in_zip_read_info->stream.avail_in = (uInt) uReadThis;
1015 } 1075 }
1016 1076
1017 if (pfile_in_zip_read_info->compression_method==0) 1077 if (0 == pfile_in_zip_read_info->compression_method)
1018 { 1078 {
1019 uInt uDoCopy; 1079 uInt uDoCopy;
1020 uInt i; 1080
1021 1081 if ( (0 == pfile_in_zip_read_info->stream.avail_in) &&
1022 if ((pfile_in_zip_read_info->stream.avail_in == 0) && 1082 (0 == pfile_in_zip_read_info->rest_read_compressed) )
1023 (pfile_in_zip_read_info->rest_read_compressed == 0)) 1083 return (0 == iRead) ? EXTRACTOR_UNZIP_EOF : iRead;
1024 return (iRead==0) ? EXTRACTOR_UNZIP_EOF : iRead; 1084
1025 1085 if (pfile_in_zip_read_info->stream.avail_out <
1026 if (pfile_in_zip_read_info->stream.avail_out < 1086 pfile_in_zip_read_info->stream.avail_in)
1027 pfile_in_zip_read_info->stream.avail_in) 1087 uDoCopy = pfile_in_zip_read_info->stream.avail_out;
1028 uDoCopy = pfile_in_zip_read_info->stream.avail_out ; 1088 else
1029 else 1089 uDoCopy = pfile_in_zip_read_info->stream.avail_in;
1030 uDoCopy = pfile_in_zip_read_info->stream.avail_in ; 1090 memcpy (pfile_in_zip_read_info->stream.next_out,
1031 1091 pfile_in_zip_read_info->stream.next_in,
1032 for (i=0;i<uDoCopy;i++) 1092 uDoCopy);
1033 *(pfile_in_zip_read_info->stream.next_out+i) = 1093 pfile_in_zip_read_info->crc32 = crc32 (pfile_in_zip_read_info->crc32,
1034 *(pfile_in_zip_read_info->stream.next_in+i); 1094 pfile_in_zip_read_info->stream.next_out,
1035 1095 uDoCopy);
1036 pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32, 1096 pfile_in_zip_read_info->rest_read_uncompressed -= uDoCopy;
1037 pfile_in_zip_read_info->stream.next_out, 1097 pfile_in_zip_read_info->stream.avail_in -= uDoCopy;
1038 uDoCopy); 1098 pfile_in_zip_read_info->stream.avail_out -= uDoCopy;
1039 pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy; 1099 pfile_in_zip_read_info->stream.next_out += uDoCopy;
1040 pfile_in_zip_read_info->stream.avail_in -= uDoCopy; 1100 pfile_in_zip_read_info->stream.next_in += uDoCopy;
1041 pfile_in_zip_read_info->stream.avail_out -= uDoCopy; 1101 pfile_in_zip_read_info->stream.total_out += uDoCopy;
1042 pfile_in_zip_read_info->stream.next_out += uDoCopy; 1102 iRead += uDoCopy;
1043 pfile_in_zip_read_info->stream.next_in += uDoCopy; 1103 }
1044 pfile_in_zip_read_info->stream.total_out += uDoCopy; 1104 else
1045 iRead += uDoCopy; 1105 {
1046 } 1106 uLong uTotalOutBefore;
1047 else 1107 uLong uTotalOutAfter;
1048 { 1108 const Bytef *bufBefore;
1049 uLong uTotalOutBefore; 1109 uLong uOutThis;
1050 uLong uTotalOutAfter; 1110 int flush = Z_SYNC_FLUSH;
1051 const Bytef *bufBefore; 1111
1052 uLong uOutThis; 1112 uTotalOutBefore = pfile_in_zip_read_info->stream.total_out;
1053 int flush = Z_SYNC_FLUSH; 1113 bufBefore = pfile_in_zip_read_info->stream.next_out;
1054 1114
1055 uTotalOutBefore = pfile_in_zip_read_info->stream.total_out; 1115 /*
1056 bufBefore = pfile_in_zip_read_info->stream.next_out; 1116 if ((pfile_in_zip_read_info->rest_read_uncompressed ==
1057 1117 pfile_in_zip_read_info->stream.avail_out) &&
1058 /* 1118 (pfile_in_zip_read_info->rest_read_compressed == 0))
1059 if ((pfile_in_zip_read_info->rest_read_uncompressed == 1119 flush = Z_FINISH;
1060 pfile_in_zip_read_info->stream.avail_out) && 1120 */
1061 (pfile_in_zip_read_info->rest_read_compressed == 0)) 1121 err = inflate (&pfile_in_zip_read_info->stream, flush);
1062 flush = Z_FINISH; 1122
1063 */ 1123 uTotalOutAfter = pfile_in_zip_read_info->stream.total_out;
1064 err = inflate(&pfile_in_zip_read_info->stream,flush); 1124 uOutThis = uTotalOutAfter-uTotalOutBefore;
1065 1125
1066 uTotalOutAfter = pfile_in_zip_read_info->stream.total_out; 1126 pfile_in_zip_read_info->crc32 =
1067 uOutThis = uTotalOutAfter-uTotalOutBefore; 1127 crc32 (pfile_in_zip_read_info->crc32, bufBefore,
1068 1128 (uInt) (uOutThis));
1069 pfile_in_zip_read_info->crc32 = 1129
1070 crc32(pfile_in_zip_read_info->crc32,bufBefore, 1130 pfile_in_zip_read_info->rest_read_uncompressed -=
1071 (uInt)(uOutThis)); 1131 uOutThis;
1072 1132
1073 pfile_in_zip_read_info->rest_read_uncompressed -= 1133 iRead += (uInt) (uTotalOutAfter - uTotalOutBefore);
1074 uOutThis; 1134
1075 1135 if (Z_STREAM_END == err)
1076 iRead += (uInt)(uTotalOutAfter - uTotalOutBefore); 1136 return (0 == iRead) ? EXTRACTOR_UNZIP_EOF : iRead;
1077 1137 if (Z_OK != err)
1078 if (Z_STREAM_END == err) 1138 break;
1079 return (0 == iRead) ? EXTRACTOR_UNZIP_EOF : iRead; 1139 }
1080 if (Z_OK != err)
1081 break;
1082 }
1083 } 1140 }
1084 1141
1085 if (Z_OK == err) 1142 if (Z_OK == err)
@@ -1089,24 +1146,28 @@ EXTRACTOR_common_unzip_read_current_file (struct EXTRACTOR_UnzipFile *file,
1089 1146
1090 1147
1091/** 1148/**
1092 * Read the local header of the current zipfile 1149 * Read the local header of the current zipfile. Check the coherency of
1093 * Check the coherency of the local header and info in the end of central 1150 * the local header and info in the end of central directory about
1094 * directory about this file 1151 * this file. Store in *piSizeVar the size of extra info in local
1095 * store in *piSizeVar the size of extra info in local header 1152 * header (filename and size of extra field data)
1096 * (filename and size of extra field data) 1153 *
1154 * @param file zipfile to process
1155 * @param piSizeVar where to store the size of the extra info
1156 * @param poffset_local_extrafield where to store the offset of the local extrafield
1157 * @param psoze_local_extrafield where to store the size of the local extrafield
1158 * @return EXTRACTOR_UNZIP_OK on success
1097 */ 1159 */
1098static int 1160static int
1099unzlocal_CheckCurrentFileCoherencyHeader (struct EXTRACTOR_UnzipFile *file, 1161parse_current_file_coherency_header (struct EXTRACTOR_UnzipFile *file,
1100 uInt *piSizeVar, 1162 uInt *piSizeVar,
1101 uLong *poffset_local_extrafield, 1163 uLong *poffset_local_extrafield,
1102 uInt *psize_local_extrafield) 1164 uInt *psize_local_extrafield)
1103{ 1165{
1104 uLong uMagic; 1166 uLong uMagic;
1105 uLong uData; 1167 uLong uData;
1106 uLong uFlags; 1168 uLong uFlags;
1107 uLong size_filename; 1169 uLong size_filename;
1108 uLong size_extra_field; 1170 uLong size_extra_field;
1109 int err = EXTRACTOR_UNZIP_OK;
1110 1171
1111 *piSizeVar = 0; 1172 *piSizeVar = 0;
1112 *poffset_local_extrafield = 0; 1173 *poffset_local_extrafield = 0;
@@ -1118,76 +1179,61 @@ unzlocal_CheckCurrentFileCoherencyHeader (struct EXTRACTOR_UnzipFile *file,
1118 SEEK_SET)) 1179 SEEK_SET))
1119 return EXTRACTOR_UNZIP_ERRNO; 1180 return EXTRACTOR_UNZIP_ERRNO;
1120 if (EXTRACTOR_UNZIP_OK != 1181 if (EXTRACTOR_UNZIP_OK !=
1121 unzlocal_getLong (&file->z_filefunc, 1182 read_long_from_ffd (&file->z_filefunc,
1122 &uMagic)) 1183 &uMagic))
1123 err = EXTRACTOR_UNZIP_ERRNO; 1184 return EXTRACTOR_UNZIP_ERRNO;
1124 else if (0x04034b50 != uMagic) 1185 if (0x04034b50 != uMagic)
1125 err = EXTRACTOR_UNZIP_BADZIPFILE; 1186 return EXTRACTOR_UNZIP_BADZIPFILE;
1126 if ( (EXTRACTOR_UNZIP_OK != 1187 if ( (EXTRACTOR_UNZIP_OK !=
1127 unzlocal_getShort (&file->z_filefunc, &uData)) || 1188 read_short_from_ffd (&file->z_filefunc, &uData)) ||
1128 (EXTRACTOR_UNZIP_OK != 1189 (EXTRACTOR_UNZIP_OK !=
1129 unzlocal_getShort (&file->z_filefunc, &uFlags)) ) 1190 read_short_from_ffd (&file->z_filefunc, &uFlags)) )
1130 err = EXTRACTOR_UNZIP_ERRNO; 1191 return EXTRACTOR_UNZIP_ERRNO;
1131 1192 if (EXTRACTOR_UNZIP_OK != read_short_from_ffd (&file->z_filefunc, &uData))
1132 if (EXTRACTOR_UNZIP_OK != unzlocal_getShort (&file->z_filefunc, &uData)) 1193 return EXTRACTOR_UNZIP_ERRNO;
1133 err = EXTRACTOR_UNZIP_ERRNO; 1194 if (uData != file->cur_file_info.compression_method)
1134 else if ((EXTRACTOR_UNZIP_OK == err) && 1195 return EXTRACTOR_UNZIP_BADZIPFILE;
1135 (uData != file->cur_file_info.compression_method)) 1196 if ( (0 != file->cur_file_info.compression_method) &&
1136 err = EXTRACTOR_UNZIP_BADZIPFILE;
1137
1138 if ( (EXTRACTOR_UNZIP_OK == err) &&
1139 (0 != file->cur_file_info.compression_method) &&
1140 (Z_DEFLATED != file->cur_file_info.compression_method) ) 1197 (Z_DEFLATED != file->cur_file_info.compression_method) )
1141 err = EXTRACTOR_UNZIP_BADZIPFILE; 1198 return EXTRACTOR_UNZIP_BADZIPFILE;
1142
1143 if (EXTRACTOR_UNZIP_OK != 1199 if (EXTRACTOR_UNZIP_OK !=
1144 unzlocal_getLong (&file->z_filefunc, &uData)) /* date/time */ 1200 read_long_from_ffd (&file->z_filefunc, &uData)) /* date/time */
1145 err = EXTRACTOR_UNZIP_ERRNO; 1201 return EXTRACTOR_UNZIP_ERRNO;
1146
1147 if (EXTRACTOR_UNZIP_OK != 1202 if (EXTRACTOR_UNZIP_OK !=
1148 unzlocal_getLong (&file->z_filefunc, &uData)) /* crc */ 1203 read_long_from_ffd (&file->z_filefunc, &uData)) /* crc */
1149 err = EXTRACTOR_UNZIP_ERRNO; 1204 return EXTRACTOR_UNZIP_ERRNO;
1150 else if ( (EXTRACTOR_UNZIP_OK == err) && 1205 if ( (uData != file->cur_file_info.crc) &&
1151 (uData != file->cur_file_info.crc) && 1206 (0 == (uFlags & 8)) )
1152 (0 == (uFlags & 8)) ) 1207 return EXTRACTOR_UNZIP_BADZIPFILE;
1153 err = EXTRACTOR_UNZIP_BADZIPFILE;
1154
1155 if (EXTRACTOR_UNZIP_OK != 1208 if (EXTRACTOR_UNZIP_OK !=
1156 unzlocal_getLong(&file->z_filefunc, &uData)) /* size compr */ 1209 read_long_from_ffd(&file->z_filefunc, &uData)) /* size compr */
1157 err = EXTRACTOR_UNZIP_ERRNO; 1210 return EXTRACTOR_UNZIP_ERRNO;
1158 else if ( (EXTRACTOR_UNZIP_OK == err) && 1211 if ( (uData != file->cur_file_info.compressed_size) &&
1159 (uData != file->cur_file_info.compressed_size) && 1212 (0 == (uFlags & 8)) )
1160 (0 == (uFlags & 8)) ) 1213 return EXTRACTOR_UNZIP_BADZIPFILE;
1161 err = EXTRACTOR_UNZIP_BADZIPFILE;
1162
1163 if (EXTRACTOR_UNZIP_OK != 1214 if (EXTRACTOR_UNZIP_OK !=
1164 unzlocal_getLong (&file->z_filefunc, 1215 read_long_from_ffd (&file->z_filefunc,
1165 &uData)) /* size uncompr */ 1216 &uData)) /* size uncompr */
1166 err = EXTRACTOR_UNZIP_ERRNO; 1217 return EXTRACTOR_UNZIP_ERRNO;
1167 else if ( (EXTRACTOR_UNZIP_OK == err) && 1218 if ( (uData != file->cur_file_info.uncompressed_size) &&
1168 (uData != file->cur_file_info.uncompressed_size) && 1219 (0 == (uFlags & 8)))
1169 (0 == (uFlags & 8))) 1220 return EXTRACTOR_UNZIP_BADZIPFILE;
1170 err = EXTRACTOR_UNZIP_BADZIPFILE;
1171
1172 if (EXTRACTOR_UNZIP_OK != 1221 if (EXTRACTOR_UNZIP_OK !=
1173 unzlocal_getShort (&file->z_filefunc, &size_filename)) 1222 read_short_from_ffd (&file->z_filefunc, &size_filename))
1174 err = EXTRACTOR_UNZIP_ERRNO; 1223 return EXTRACTOR_UNZIP_ERRNO;
1175 else if ( (EXTRACTOR_UNZIP_OK == err) && 1224 if (size_filename != file->cur_file_info.size_filename)
1176 (size_filename != file->cur_file_info.size_filename) ) 1225 return EXTRACTOR_UNZIP_BADZIPFILE;
1177 err = EXTRACTOR_UNZIP_BADZIPFILE;
1178
1179 *piSizeVar += (uInt) size_filename; 1226 *piSizeVar += (uInt) size_filename;
1180
1181 if (EXTRACTOR_UNZIP_OK != 1227 if (EXTRACTOR_UNZIP_OK !=
1182 unzlocal_getShort (&file->z_filefunc, 1228 read_short_from_ffd (&file->z_filefunc,
1183 &size_extra_field)) 1229 &size_extra_field))
1184 err = EXTRACTOR_UNZIP_ERRNO; 1230 return EXTRACTOR_UNZIP_ERRNO;
1185 *poffset_local_extrafield = file->cur_file_info_internal.offset_curfile + 1231 *poffset_local_extrafield = file->cur_file_info_internal.offset_curfile +
1186 SIZEZIPLOCALHEADER + size_filename; 1232 SIZEZIPLOCALHEADER + size_filename;
1187 *psize_local_extrafield = (uInt) size_extra_field; 1233 *psize_local_extrafield = (uInt) size_extra_field;
1188 *piSizeVar += (uInt)size_extra_field; 1234 *piSizeVar += (uInt)size_extra_field;
1189 1235
1190 return err; 1236 return EXTRACTOR_UNZIP_OK;
1191} 1237}
1192 1238
1193 1239
@@ -1200,7 +1246,7 @@ unzlocal_CheckCurrentFileCoherencyHeader (struct EXTRACTOR_UnzipFile *file,
1200int 1246int
1201EXTRACTOR_common_unzip_open_current_file (struct EXTRACTOR_UnzipFile *file) 1247EXTRACTOR_common_unzip_open_current_file (struct EXTRACTOR_UnzipFile *file)
1202{ 1248{
1203 int err = EXTRACTOR_UNZIP_OK; 1249 int err;
1204 uInt iSizeVar; 1250 uInt iSizeVar;
1205 struct FileInZipReadInfo *pfile_in_zip_read_info; 1251 struct FileInZipReadInfo *pfile_in_zip_read_info;
1206 uLong offset_local_extrafield; /* offset of the local extra field */ 1252 uLong offset_local_extrafield; /* offset of the local extra field */
@@ -1213,14 +1259,14 @@ EXTRACTOR_common_unzip_open_current_file (struct EXTRACTOR_UnzipFile *file)
1213 if (NULL != file->pfile_in_zip_read) 1259 if (NULL != file->pfile_in_zip_read)
1214 EXTRACTOR_common_unzip_close_current_file (file); 1260 EXTRACTOR_common_unzip_close_current_file (file);
1215 if (EXTRACTOR_UNZIP_OK != 1261 if (EXTRACTOR_UNZIP_OK !=
1216 unzlocal_CheckCurrentFileCoherencyHeader (file, 1262 parse_current_file_coherency_header (file,
1217 &iSizeVar, 1263 &iSizeVar,
1218 &offset_local_extrafield, 1264 &offset_local_extrafield,
1219 &size_local_extrafield)) 1265 &size_local_extrafield))
1220 return EXTRACTOR_UNZIP_BADZIPFILE; 1266 return EXTRACTOR_UNZIP_BADZIPFILE;
1221 if (NULL == (pfile_in_zip_read_info = malloc(sizeof(struct FileInZipReadInfo)))) 1267 if (NULL == (pfile_in_zip_read_info = malloc (sizeof(struct FileInZipReadInfo))))
1222 return EXTRACTOR_UNZIP_INTERNALERROR; 1268 return EXTRACTOR_UNZIP_INTERNALERROR;
1223 if (NULL == (pfile_in_zip_read_info->read_buffer = malloc(UNZ_BUFSIZE))) 1269 if (NULL == (pfile_in_zip_read_info->read_buffer = malloc (UNZ_BUFSIZE)))
1224 { 1270 {
1225 free (pfile_in_zip_read_info); 1271 free (pfile_in_zip_read_info);
1226 return EXTRACTOR_UNZIP_INTERNALERROR; 1272 return EXTRACTOR_UNZIP_INTERNALERROR;
@@ -1232,7 +1278,11 @@ EXTRACTOR_common_unzip_open_current_file (struct EXTRACTOR_UnzipFile *file)
1232 1278
1233 if ( (0 != file->cur_file_info.compression_method) && 1279 if ( (0 != file->cur_file_info.compression_method) &&
1234 (Z_DEFLATED != file->cur_file_info.compression_method) ) 1280 (Z_DEFLATED != file->cur_file_info.compression_method) )
1235 err = EXTRACTOR_UNZIP_BADZIPFILE; 1281 {
1282 // err = EXTRACTOR_UNZIP_BADZIPFILE;
1283 // FIXME: we don't do anything with this 'err' code.
1284 // Can this happen? Should we abort in this case?
1285 }
1236 1286
1237 pfile_in_zip_read_info->crc32_wait = file->cur_file_info.crc; 1287 pfile_in_zip_read_info->crc32_wait = file->cur_file_info.crc;
1238 pfile_in_zip_read_info->crc32 = 0; 1288 pfile_in_zip_read_info->crc32 = 0;
@@ -1240,8 +1290,7 @@ EXTRACTOR_common_unzip_open_current_file (struct EXTRACTOR_UnzipFile *file)
1240 pfile_in_zip_read_info->z_filefunc = file->z_filefunc; 1290 pfile_in_zip_read_info->z_filefunc = file->z_filefunc;
1241 pfile_in_zip_read_info->byte_before_the_zipfile = file->byte_before_the_zipfile; 1291 pfile_in_zip_read_info->byte_before_the_zipfile = file->byte_before_the_zipfile;
1242 pfile_in_zip_read_info->stream.total_out = 0; 1292 pfile_in_zip_read_info->stream.total_out = 0;
1243 1293 if (Z_DEFLATED == file->cur_file_info.compression_method)
1244 if (file->cur_file_info.compression_method==Z_DEFLATED)
1245 { 1294 {
1246 pfile_in_zip_read_info->stream.zalloc = (alloc_func) NULL; 1295 pfile_in_zip_read_info->stream.zalloc = (alloc_func) NULL;
1247 pfile_in_zip_read_info->stream.zfree = (free_func) NULL; 1296 pfile_in_zip_read_info->stream.zfree = (free_func) NULL;
@@ -1270,11 +1319,19 @@ EXTRACTOR_common_unzip_open_current_file (struct EXTRACTOR_UnzipFile *file)
1270 iSizeVar; 1319 iSizeVar;
1271 pfile_in_zip_read_info->stream.avail_in = 0; 1320 pfile_in_zip_read_info->stream.avail_in = 0;
1272 file->pfile_in_zip_read = pfile_in_zip_read_info; 1321 file->pfile_in_zip_read = pfile_in_zip_read_info;
1273
1274 return EXTRACTOR_UNZIP_OK; 1322 return EXTRACTOR_UNZIP_OK;
1275} 1323}
1276 1324
1277 1325
1326/**
1327 * Callback to perform read operation using LE API.
1328 * Note that partial reads are not allowed.
1329 *
1330 * @param opaque the 'struct EXTRACTOR_ExtractContext'
1331 * @param buf where to write bytes read
1332 * @param size number of bytes desired
1333 * @return number of bytes copied to buf
1334 */
1278static uLong 1335static uLong
1279ec_read_file_func (voidpf opaque, 1336ec_read_file_func (voidpf opaque,
1280 void* buf, 1337 void* buf,
@@ -1283,17 +1340,29 @@ ec_read_file_func (voidpf opaque,
1283 struct EXTRACTOR_ExtractContext *ec = opaque; 1340 struct EXTRACTOR_ExtractContext *ec = opaque;
1284 void *ptr; 1341 void *ptr;
1285 ssize_t ret; 1342 ssize_t ret;
1343 uLong done;
1286 1344
1287 ret = ec->read (ec->cls, 1345 done = 0;
1288 &ptr, 1346 while (done < size)
1289 size); 1347 {
1290 if (ret > 0) 1348 ret = ec->read (ec->cls,
1291 memcpy (buf, ptr, ret); 1349 &ptr,
1292 // FIXME: partial reads are not allowed, need to possibly read more 1350 size);
1293 return ret; 1351 if (ret <= 0)
1352 return done;
1353 memcpy (buf + done, ptr, ret);
1354 done += ret;
1355 }
1356 return done;
1294} 1357}
1295 1358
1296 1359
1360/**
1361 * Callback to obtain current offset in file using LE API.
1362 *
1363 * @param opaque the 'struct EXTRACTOR_ExtractContext'
1364 * @return current offset in file, -1 on error
1365 */
1297static long 1366static long
1298ec_tell_file_func (voidpf opaque) 1367ec_tell_file_func (voidpf opaque)
1299{ 1368{
@@ -1303,6 +1372,14 @@ ec_tell_file_func (voidpf opaque)
1303} 1372}
1304 1373
1305 1374
1375/**
1376 * Callback to perform seek operation using LE API.
1377 *
1378 * @param opaque the 'struct EXTRACTOR_ExtractContext'
1379 * @param offset where to seek
1380 * @param origin relative to where should we seek
1381 * @return EXTRACTOR_UNZIP_OK on success
1382 */
1306static long 1383static long
1307ec_seek_file_func (voidpf opaque, 1384ec_seek_file_func (voidpf opaque,
1308 uLong offset, 1385 uLong offset,
@@ -1326,14 +1403,14 @@ ec_seek_file_func (voidpf opaque,
1326struct EXTRACTOR_UnzipFile * 1403struct EXTRACTOR_UnzipFile *
1327EXTRACTOR_common_unzip_open (struct EXTRACTOR_ExtractContext *ec) 1404EXTRACTOR_common_unzip_open (struct EXTRACTOR_ExtractContext *ec)
1328{ 1405{
1329 struct EXTRACTOR_UnzipFileFuncDefs io; 1406 struct FileFuncDefs ffd;
1330 1407
1331 io.zread_file = &ec_read_file_func; 1408 ffd.zread_file = &ec_read_file_func;
1332 io.ztell_file = &ec_tell_file_func; 1409 ffd.ztell_file = &ec_tell_file_func;
1333 io.zseek_file = &ec_seek_file_func; 1410 ffd.zseek_file = &ec_seek_file_func;
1334 io.opaque = ec; 1411 ffd.opaque = ec;
1335 1412
1336 return EXTRACTOR_common_unzip_open2 (&io); 1413 return unzip_open_using_ffd (&ffd);
1337} 1414}
1338 1415
1339/* end of unzip.c */ 1416/* end of unzip.c */