aboutsummaryrefslogtreecommitdiff
path: root/archival
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2010-10-28 23:08:53 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2010-10-28 23:08:53 +0200
commitcaddfc83399ab783f032dbe23f3b10a5bd85414f (patch)
tree91dc667eaafc3846f4c7089d7393f47821df641d /archival
parent8410ac1a073272affe8acdb0da67e5753ea051f8 (diff)
downloadbusybox-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.c74
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! */
587int FAST_FUNC start_bunzip(bunzip_data **bdp, int in_fd, const unsigned char *inbuf, 587int 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
652unpack_bz2_stream(int src_fd, int dst_fd) 654unpack_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