diff options
Diffstat (limited to 'src/common/unzip.c')
-rw-r--r-- | src/common/unzip.c | 977 |
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 | */ |
52 | struct EXTRACTOR_UnzipFileFuncDefs | 85 | struct 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 | */ |
296 | static int | 338 | static int |
297 | unzlocal_getByte (const struct EXTRACTOR_UnzipFileFuncDefs* pzlib_filefunc_def, | 339 | read_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 | */ | ||
309 | static int | 360 | static int |
310 | unzlocal_getShort (const struct EXTRACTOR_UnzipFileFuncDefs* pzlib_filefunc_def, | 361 | read_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 | */ | ||
329 | static int | 389 | static int |
330 | unzlocal_getLong (const struct EXTRACTOR_UnzipFileFuncDefs* pzlib_filefunc_def, | 390 | read_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 | */ |
399 | static uLong | 462 | static uLong |
400 | unzlocal_SearchCentralDir (const struct EXTRACTOR_UnzipFileFuncDefs* pzlib_filefunc_def) | 463 | locate_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 | */ |
462 | static void | 513 | static void |
463 | unzlocal_DosDateToTmuDate (uLong ulDosDate, | 514 | dos_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 | */ | ||
478 | static int | 544 | static int |
479 | unzlocal_GetCurrentFileInfoInternal (struct EXTRACTOR_UnzipFile *s, | 545 | get_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 | */ |
667 | static struct EXTRACTOR_UnzipFile * | 723 | static struct EXTRACTOR_UnzipFile * |
668 | EXTRACTOR_common_unzip_open2 (struct EXTRACTOR_UnzipFileFuncDefs *pzlib_filefunc_def) | 724 | unzip_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 | */ |
761 | int | 815 | int |
762 | EXTRACTOR_common_unzip_close_current_file (struct EXTRACTOR_UnzipFile * file) | 816 | EXTRACTOR_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) | |||
808 | int | 846 | int |
809 | EXTRACTOR_common_unzip_close (struct EXTRACTOR_UnzipFile *file) | 847 | EXTRACTOR_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 | */ | ||
866 | int | ||
867 | EXTRACTOR_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 | */ |
862 | int | 924 | int |
863 | EXTRACTOR_common_unzip_go_to_next_file (struct EXTRACTOR_UnzipFile * file) | 925 | EXTRACTOR_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 | */ |
1098 | static int | 1160 | static int |
1099 | unzlocal_CheckCurrentFileCoherencyHeader (struct EXTRACTOR_UnzipFile *file, | 1161 | parse_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, | |||
1200 | int | 1246 | int |
1201 | EXTRACTOR_common_unzip_open_current_file (struct EXTRACTOR_UnzipFile *file) | 1247 | EXTRACTOR_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 | */ | ||
1278 | static uLong | 1335 | static uLong |
1279 | ec_read_file_func (voidpf opaque, | 1336 | ec_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 | */ | ||
1297 | static long | 1366 | static long |
1298 | ec_tell_file_func (voidpf opaque) | 1367 | ec_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 | */ | ||
1306 | static long | 1383 | static long |
1307 | ec_seek_file_func (voidpf opaque, | 1384 | ec_seek_file_func (voidpf opaque, |
1308 | uLong offset, | 1385 | uLong offset, |
@@ -1326,14 +1403,14 @@ ec_seek_file_func (voidpf opaque, | |||
1326 | struct EXTRACTOR_UnzipFile * | 1403 | struct EXTRACTOR_UnzipFile * |
1327 | EXTRACTOR_common_unzip_open (struct EXTRACTOR_ExtractContext *ec) | 1404 | EXTRACTOR_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 */ |