aboutsummaryrefslogtreecommitdiff
path: root/archival
diff options
context:
space:
mode:
Diffstat (limited to 'archival')
-rw-r--r--archival/libarchive/Kbuild.src1
-rw-r--r--archival/libarchive/decompress_bunzip2.c40
-rw-r--r--archival/libarchive/decompress_unlzma.c20
-rw-r--r--archival/libarchive/get_header_tar.c3
-rw-r--r--archival/libarchive/open_transformer.c3
-rw-r--r--archival/tar.c8
6 files changed, 60 insertions, 15 deletions
diff --git a/archival/libarchive/Kbuild.src b/archival/libarchive/Kbuild.src
index e1a8a7529..d2f284b08 100644
--- a/archival/libarchive/Kbuild.src
+++ b/archival/libarchive/Kbuild.src
@@ -91,6 +91,7 @@ lib-$(CONFIG_FEATURE_SEAMLESS_LZMA) += open_transformer.o decompress_unlzma.
91lib-$(CONFIG_FEATURE_SEAMLESS_XZ) += open_transformer.o decompress_unxz.o 91lib-$(CONFIG_FEATURE_SEAMLESS_XZ) += open_transformer.o decompress_unxz.o
92lib-$(CONFIG_FEATURE_COMPRESS_USAGE) += open_transformer.o decompress_bunzip2.o 92lib-$(CONFIG_FEATURE_COMPRESS_USAGE) += open_transformer.o decompress_bunzip2.o
93lib-$(CONFIG_FEATURE_COMPRESS_BBCONFIG) += open_transformer.o decompress_bunzip2.o 93lib-$(CONFIG_FEATURE_COMPRESS_BBCONFIG) += open_transformer.o decompress_bunzip2.o
94lib-$(CONFIG_FEATURE_SH_EMBEDDED_SCRIPTS) += open_transformer.o decompress_bunzip2.o
94 95
95ifneq ($(lib-y),) 96ifneq ($(lib-y),)
96lib-y += $(COMMON_FILES) 97lib-y += $(COMMON_FILES)
diff --git a/archival/libarchive/decompress_bunzip2.c b/archival/libarchive/decompress_bunzip2.c
index 7ef4e035f..78366f26a 100644
--- a/archival/libarchive/decompress_bunzip2.c
+++ b/archival/libarchive/decompress_bunzip2.c
@@ -107,7 +107,7 @@ struct bunzip_data {
107 uint8_t selectors[32768]; /* nSelectors=15 bits */ 107 uint8_t selectors[32768]; /* nSelectors=15 bits */
108 struct group_data groups[MAX_GROUPS]; /* Huffman coding tables */ 108 struct group_data groups[MAX_GROUPS]; /* Huffman coding tables */
109}; 109};
110/* typedef struct bunzip_data bunzip_data; -- done in .h file */ 110typedef struct bunzip_data bunzip_data;
111 111
112 112
113/* Return the next nnn bits of input. All reads from the compressed input 113/* Return the next nnn bits of input. All reads from the compressed input
@@ -575,7 +575,7 @@ static int get_next_block(bunzip_data *bd)
575 in outbuf. IOW: on EOF returns len ("all bytes are not filled"), not 0. 575 in outbuf. IOW: on EOF returns len ("all bytes are not filled"), not 0.
576 (Why? This allows to get rid of one local variable) 576 (Why? This allows to get rid of one local variable)
577*/ 577*/
578int FAST_FUNC read_bunzip(bunzip_data *bd, char *outbuf, int len) 578static int read_bunzip(bunzip_data *bd, char *outbuf, int len)
579{ 579{
580 const uint32_t *dbuf; 580 const uint32_t *dbuf;
581 int pos, current, previous; 581 int pos, current, previous;
@@ -699,7 +699,7 @@ int FAST_FUNC read_bunzip(bunzip_data *bd, char *outbuf, int len)
699/* Because bunzip2 is used for help text unpacking, and because bb_show_usage() 699/* Because bunzip2 is used for help text unpacking, and because bb_show_usage()
700 should work for NOFORK applets too, we must be extremely careful to not leak 700 should work for NOFORK applets too, we must be extremely careful to not leak
701 any allocations! */ 701 any allocations! */
702int FAST_FUNC start_bunzip( 702static int FAST_FUNC start_bunzip(
703 void *jmpbuf, 703 void *jmpbuf,
704 bunzip_data **bdp, 704 bunzip_data **bdp,
705 int in_fd, 705 int in_fd,
@@ -759,7 +759,7 @@ int FAST_FUNC start_bunzip(
759 return RETVAL_OK; 759 return RETVAL_OK;
760} 760}
761 761
762void FAST_FUNC dealloc_bunzip(bunzip_data *bd) 762static void FAST_FUNC dealloc_bunzip(bunzip_data *bd)
763{ 763{
764 free(bd->dbuf); 764 free(bd->dbuf);
765 free(bd); 765 free(bd);
@@ -809,7 +809,7 @@ unpack_bz2_stream(transformer_state_t *xstate)
809 /* Observed case when i == RETVAL_OK: 809 /* Observed case when i == RETVAL_OK:
810 * "bzcat z.bz2", where "z.bz2" is a bzipped zero-length file 810 * "bzcat z.bz2", where "z.bz2" is a bzipped zero-length file
811 * (to be exact, z.bz2 is exactly these 14 bytes: 811 * (to be exact, z.bz2 is exactly these 14 bytes:
812 * 42 5a 68 39 17 72 45 38 50 90 00 00 00 00). 812 * 42 5a 68 39 17 72 45 38 50 90 00 00 00 00).
813 */ 813 */
814 && i != RETVAL_OK 814 && i != RETVAL_OK
815 ) { 815 ) {
@@ -847,6 +847,36 @@ unpack_bz2_stream(transformer_state_t *xstate)
847 return i ? i : IF_DESKTOP(total_written) + 0; 847 return i ? i : IF_DESKTOP(total_written) + 0;
848} 848}
849 849
850char* FAST_FUNC
851unpack_bz2_data(const char *packed, int packed_len, int unpacked_len)
852{
853 char *outbuf = NULL;
854 bunzip_data *bd;
855 int i;
856 jmp_buf jmpbuf;
857
858 /* Setup for I/O error handling via longjmp */
859 i = setjmp(jmpbuf);
860 if (i == 0) {
861 i = start_bunzip(&jmpbuf,
862 &bd,
863 /* src_fd: */ -1,
864 /* inbuf: */ packed,
865 /* len: */ packed_len
866 );
867 }
868 /* read_bunzip can longjmp and end up here with i != 0
869 * on read data errors! Not trivial */
870 if (i == 0) {
871 /* Cannot use xmalloc: will leak bd in NOFORK case! */
872 outbuf = malloc_or_warn(unpacked_len);
873 if (outbuf)
874 read_bunzip(bd, outbuf, unpacked_len);
875 }
876 dealloc_bunzip(bd);
877 return outbuf;
878}
879
850#ifdef TESTING 880#ifdef TESTING
851 881
852static char *const bunzip_errors[] = { 882static char *const bunzip_errors[] = {
diff --git a/archival/libarchive/decompress_unlzma.c b/archival/libarchive/decompress_unlzma.c
index 6886239d0..668b01618 100644
--- a/archival/libarchive/decompress_unlzma.c
+++ b/archival/libarchive/decompress_unlzma.c
@@ -353,8 +353,10 @@ unpack_lzma_stream(transformer_state_t *xstate)
353 if ((int32_t)pos < 0) { 353 if ((int32_t)pos < 0) {
354 pos += header.dict_size; 354 pos += header.dict_size;
355 /* see unzip_bad_lzma_2.zip: */ 355 /* see unzip_bad_lzma_2.zip: */
356 if (pos >= buffer_size) 356 if (pos >= buffer_size) {
357 dbg("%d pos:%d buffer_size:%d", __LINE__, pos, buffer_size);
357 goto bad; 358 goto bad;
359 }
358 } 360 }
359 previous_byte = buffer[pos]; 361 previous_byte = buffer[pos];
360 goto one_byte1; 362 goto one_byte1;
@@ -430,10 +432,9 @@ unpack_lzma_stream(transformer_state_t *xstate)
430 for (; num_bits2 != LZMA_NUM_ALIGN_BITS; num_bits2--) 432 for (; num_bits2 != LZMA_NUM_ALIGN_BITS; num_bits2--)
431 rep0 = (rep0 << 1) | rc_direct_bit(rc); 433 rep0 = (rep0 << 1) | rc_direct_bit(rc);
432 rep0 <<= LZMA_NUM_ALIGN_BITS; 434 rep0 <<= LZMA_NUM_ALIGN_BITS;
433 if ((int32_t)rep0 < 0) { 435 // Note: (int32_t)rep0 may be < 0 here
434 dbg("%d rep0:%d", __LINE__, rep0); 436 // (I have linux-3.3.4.tar.lzma which has it).
435 goto bad; 437 // I moved the check after "++rep0 == 0" check below.
436 }
437 prob3 = p + LZMA_ALIGN; 438 prob3 = p + LZMA_ALIGN;
438 } 439 }
439 i2 = 1; 440 i2 = 1;
@@ -444,8 +445,13 @@ unpack_lzma_stream(transformer_state_t *xstate)
444 i2 <<= 1; 445 i2 <<= 1;
445 } 446 }
446 } 447 }
447 if (++rep0 == 0) 448 rep0++;
448 break; 449 if ((int32_t)rep0 <= 0) {
450 if (rep0 == 0)
451 break;
452 dbg("%d rep0:%d", __LINE__, rep0);
453 goto bad;
454 }
449 } 455 }
450 456
451 len += LZMA_MATCH_MIN_LEN; 457 len += LZMA_MATCH_MIN_LEN;
diff --git a/archival/libarchive/get_header_tar.c b/archival/libarchive/get_header_tar.c
index 5c495e14e..52fa4554a 100644
--- a/archival/libarchive/get_header_tar.c
+++ b/archival/libarchive/get_header_tar.c
@@ -414,7 +414,8 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle)
414// case 'D': /* GNU dump dir */ 414// case 'D': /* GNU dump dir */
415// case 'M': /* Continuation of multi volume archive */ 415// case 'M': /* Continuation of multi volume archive */
416// case 'N': /* Old GNU for names > 100 characters */ 416// case 'N': /* Old GNU for names > 100 characters */
417// case 'V': /* Volume header */ 417 case 'V': /* Volume header */
418 ; /* Fall through to skip it */
418#endif 419#endif
419 } 420 }
420 skip_ext_hdr: 421 skip_ext_hdr:
diff --git a/archival/libarchive/open_transformer.c b/archival/libarchive/open_transformer.c
index 0160a64fe..399ee03a7 100644
--- a/archival/libarchive/open_transformer.c
+++ b/archival/libarchive/open_transformer.c
@@ -304,8 +304,7 @@ static transformer_state_t *open_transformer(const char *fname, int fail_if_not_
304 304
305 if (ENABLE_FEATURE_SEAMLESS_LZMA) { 305 if (ENABLE_FEATURE_SEAMLESS_LZMA) {
306 /* .lzma has no header/signature, can only detect it by extension */ 306 /* .lzma has no header/signature, can only detect it by extension */
307 char *sfx = strrchr(fname, '.'); 307 if (is_suffixed_with(fname, ".lzma")) {
308 if (sfx && strcmp(sfx+1, "lzma") == 0) {
309 xstate = xzalloc(sizeof(*xstate)); 308 xstate = xzalloc(sizeof(*xstate));
310 xstate->src_fd = fd; 309 xstate->src_fd = fd;
311 xstate->xformer = unpack_lzma_stream; 310 xstate->xformer = unpack_lzma_stream;
diff --git a/archival/tar.c b/archival/tar.c
index 9a171ceea..22ad0e0f2 100644
--- a/archival/tar.c
+++ b/archival/tar.c
@@ -1197,8 +1197,16 @@ int tar_main(int argc UNUSED_PARAM, char **argv)
1197 tar_handle->seek = seek_by_read; 1197 tar_handle->seek = seek_by_read;
1198 } else 1198 } else
1199 if (ENABLE_FEATURE_TAR_AUTODETECT 1199 if (ENABLE_FEATURE_TAR_AUTODETECT
1200 && ENABLE_FEATURE_SEAMLESS_LZMA
1200 && flags == O_RDONLY 1201 && flags == O_RDONLY
1201 && !(opt & OPT_ANY_COMPRESS) 1202 && !(opt & OPT_ANY_COMPRESS)
1203 && is_suffixed_with(tar_filename, ".lzma")
1204 /* We do this only for .lzma files, they have no signature.
1205 * All other compression formats are recognized in
1206 * get_header_tar() when first tar block has invalid format.
1207 * Doing it here for all filenames would falsely trigger
1208 * on e.g. tarball with 1st file named "BZh5".
1209 */
1202 ) { 1210 ) {
1203 tar_handle->src_fd = open_zipped(tar_filename, /*fail_if_not_compressed:*/ 0); 1211 tar_handle->src_fd = open_zipped(tar_filename, /*fail_if_not_compressed:*/ 0);
1204 if (tar_handle->src_fd < 0) 1212 if (tar_handle->src_fd < 0)