diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2010-10-28 23:08:53 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2010-10-28 23:08:53 +0200 |
commit | caddfc83399ab783f032dbe23f3b10a5bd85414f (patch) | |
tree | 91dc667eaafc3846f4c7089d7393f47821df641d /archival | |
parent | 8410ac1a073272affe8acdb0da67e5753ea051f8 (diff) | |
download | busybox-w32-caddfc83399ab783f032dbe23f3b10a5bd85414f.tar.gz busybox-w32-caddfc83399ab783f032dbe23f3b10a5bd85414f.tar.bz2 busybox-w32-caddfc83399ab783f032dbe23f3b10a5bd85414f.zip |
decompress_bunzip2: handle concatenated .bz2 files
function old new delta
unpack_bz2_stream 207 307 +100
start_bunzip 199 209 +10
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/0 up/down: 110/0) Total: 110 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'archival')
-rw-r--r-- | archival/libunarchive/decompress_bunzip2.c | 74 |
1 files changed, 49 insertions, 25 deletions
diff --git a/archival/libunarchive/decompress_bunzip2.c b/archival/libunarchive/decompress_bunzip2.c index 22015683c..549c8b19f 100644 --- a/archival/libunarchive/decompress_bunzip2.c +++ b/archival/libunarchive/decompress_bunzip2.c | |||
@@ -44,7 +44,7 @@ | |||
44 | #define RETVAL_LAST_BLOCK (-1) | 44 | #define RETVAL_LAST_BLOCK (-1) |
45 | #define RETVAL_NOT_BZIP_DATA (-2) | 45 | #define RETVAL_NOT_BZIP_DATA (-2) |
46 | #define RETVAL_UNEXPECTED_INPUT_EOF (-3) | 46 | #define RETVAL_UNEXPECTED_INPUT_EOF (-3) |
47 | #define RETVAL_SHORT_WRITE (-4) | 47 | //#define RETVAL_SHORT_WRITE (-4) |
48 | #define RETVAL_DATA_ERROR (-5) | 48 | #define RETVAL_DATA_ERROR (-5) |
49 | #define RETVAL_OUT_OF_MEMORY (-6) | 49 | #define RETVAL_OUT_OF_MEMORY (-6) |
50 | #define RETVAL_OBSOLETE_INPUT (-7) | 50 | #define RETVAL_OBSOLETE_INPUT (-7) |
@@ -584,8 +584,8 @@ int FAST_FUNC read_bunzip(bunzip_data *bd, char *outbuf, int len) | |||
584 | /* Because bunzip2 is used for help text unpacking, and because bb_show_usage() | 584 | /* Because bunzip2 is used for help text unpacking, and because bb_show_usage() |
585 | should work for NOFORK applets too, we must be extremely careful to not leak | 585 | should work for NOFORK applets too, we must be extremely careful to not leak |
586 | any allocations! */ | 586 | any allocations! */ |
587 | int FAST_FUNC start_bunzip(bunzip_data **bdp, int in_fd, const unsigned char *inbuf, | 587 | int FAST_FUNC start_bunzip(bunzip_data **bdp, int in_fd, |
588 | int len) | 588 | const void *inbuf, int len) |
589 | { | 589 | { |
590 | bunzip_data *bd; | 590 | bunzip_data *bd; |
591 | unsigned i; | 591 | unsigned i; |
@@ -606,9 +606,11 @@ int FAST_FUNC start_bunzip(bunzip_data **bdp, int in_fd, const unsigned char *in | |||
606 | if (-1 == in_fd) { | 606 | if (-1 == in_fd) { |
607 | /* in this case, bd->inbuf is read-only */ | 607 | /* in this case, bd->inbuf is read-only */ |
608 | bd->inbuf = (void*)inbuf; /* cast away const-ness */ | 608 | bd->inbuf = (void*)inbuf; /* cast away const-ness */ |
609 | bd->inbufCount = len; | 609 | } else { |
610 | } else | ||
611 | bd->inbuf = (unsigned char *)(bd + 1); | 610 | bd->inbuf = (unsigned char *)(bd + 1); |
611 | memcpy(bd->inbuf, inbuf, len); | ||
612 | } | ||
613 | bd->inbufCount = len; | ||
612 | 614 | ||
613 | /* Init the CRC32 table (big endian) */ | 615 | /* Init the CRC32 table (big endian) */ |
614 | crc32_filltable(bd->crc32Table, 1); | 616 | crc32_filltable(bd->crc32Table, 1); |
@@ -652,37 +654,59 @@ IF_DESKTOP(long long) int FAST_FUNC | |||
652 | unpack_bz2_stream(int src_fd, int dst_fd) | 654 | unpack_bz2_stream(int src_fd, int dst_fd) |
653 | { | 655 | { |
654 | IF_DESKTOP(long long total_written = 0;) | 656 | IF_DESKTOP(long long total_written = 0;) |
657 | bunzip_data *bd; | ||
655 | char *outbuf; | 658 | char *outbuf; |
656 | bunzip_data *bd; | ||
657 | int i; | 659 | int i; |
660 | unsigned len; | ||
658 | 661 | ||
659 | outbuf = xmalloc(IOBUF_SIZE); | 662 | outbuf = xmalloc(IOBUF_SIZE); |
660 | i = start_bunzip(&bd, src_fd, NULL, 0); | 663 | len = 0; |
661 | if (!i) { | 664 | while (1) { /* "Process one BZ... stream" loop */ |
662 | for (;;) { | 665 | |
663 | i = read_bunzip(bd, outbuf, IOBUF_SIZE); | 666 | i = start_bunzip(&bd, src_fd, outbuf + 2, len); |
664 | if (i <= 0) break; | 667 | |
665 | if (i != full_write(dst_fd, outbuf, i)) { | 668 | if (i == 0) { |
666 | i = RETVAL_SHORT_WRITE; | 669 | while (1) { /* "Produce some output bytes" loop */ |
667 | break; | 670 | i = read_bunzip(bd, outbuf, IOBUF_SIZE); |
671 | if (i <= 0) | ||
672 | break; | ||
673 | if (i != full_write(dst_fd, outbuf, i)) { | ||
674 | bb_error_msg("short write"); | ||
675 | goto release_mem; | ||
676 | } | ||
677 | IF_DESKTOP(total_written += i;) | ||
668 | } | 678 | } |
669 | IF_DESKTOP(total_written += i;) | ||
670 | } | 679 | } |
671 | } | ||
672 | 680 | ||
673 | /* Check CRC and release memory */ | 681 | if (i != RETVAL_LAST_BLOCK) { |
674 | 682 | bb_error_msg("bunzip error %d", i); | |
675 | if (i == RETVAL_LAST_BLOCK) { | 683 | break; |
684 | } | ||
676 | if (bd->headerCRC != bd->totalCRC) { | 685 | if (bd->headerCRC != bd->totalCRC) { |
677 | bb_error_msg("CRC error"); | 686 | bb_error_msg("CRC error"); |
678 | } else { | 687 | break; |
679 | i = RETVAL_OK; | ||
680 | } | 688 | } |
681 | } else if (i == RETVAL_SHORT_WRITE) { | 689 | |
682 | bb_error_msg("short write"); | 690 | /* Successfully unpacked one BZ stream */ |
683 | } else { | 691 | i = RETVAL_OK; |
684 | bb_error_msg("bunzip error %d", i); | 692 | |
693 | /* Do we have "BZ..." after last processed byte? | ||
694 | * pbzip2 (parallelized bzip2) produces such files. | ||
695 | */ | ||
696 | len = bd->inbufCount - bd->inbufPos; | ||
697 | memcpy(outbuf, &bd->inbuf[bd->inbufPos], len); | ||
698 | if (len < 2) { | ||
699 | if (safe_read(src_fd, outbuf + len, 2 - len) != 2 - len) | ||
700 | break; | ||
701 | len = 2; | ||
702 | } | ||
703 | if (*(uint16_t*)outbuf != BZIP2_MAGIC) /* "BZ"? */ | ||
704 | break; | ||
705 | dealloc_bunzip(bd); | ||
706 | len -= 2; | ||
685 | } | 707 | } |
708 | |||
709 | release_mem: | ||
686 | dealloc_bunzip(bd); | 710 | dealloc_bunzip(bd); |
687 | free(outbuf); | 711 | free(outbuf); |
688 | 712 | ||