aboutsummaryrefslogtreecommitdiff
path: root/archival/libarchive
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2013-03-19 11:18:39 +0000
committerRon Yorston <rmy@pobox.com>2013-03-19 11:18:39 +0000
commit63d2c5fead323df5f4250ed544d0bc03527c8936 (patch)
tree660979b139a4bc4b143c08843cb7efbc69bdcb4d /archival/libarchive
parent27fc2d535588728ac3ca69337271471fb6fe3ee9 (diff)
parenta42f530e034b673726a91ea5d8202254e677f066 (diff)
downloadbusybox-w32-63d2c5fead323df5f4250ed544d0bc03527c8936.tar.gz
busybox-w32-63d2c5fead323df5f4250ed544d0bc03527c8936.tar.bz2
busybox-w32-63d2c5fead323df5f4250ed544d0bc03527c8936.zip
Merge branch 'busybox' into merge
Diffstat (limited to 'archival/libarchive')
-rw-r--r--archival/libarchive/data_extract_all.c15
-rw-r--r--archival/libarchive/decompress_unlzma.c29
-rw-r--r--archival/libarchive/decompress_unxz.c47
-rw-r--r--archival/libarchive/open_transformer.c11
-rw-r--r--archival/libarchive/unxz/README6
-rw-r--r--archival/libarchive/unxz/xz.h17
-rw-r--r--archival/libarchive/unxz/xz_dec_bcj.c34
-rw-r--r--archival/libarchive/unxz/xz_dec_lzma2.c7
-rw-r--r--archival/libarchive/unxz/xz_stream.h11
9 files changed, 123 insertions, 54 deletions
diff --git a/archival/libarchive/data_extract_all.c b/archival/libarchive/data_extract_all.c
index 3f67b835f..45776dcbe 100644
--- a/archival/libarchive/data_extract_all.c
+++ b/archival/libarchive/data_extract_all.c
@@ -106,15 +106,28 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle)
106 switch (file_header->mode & S_IFMT) { 106 switch (file_header->mode & S_IFMT) {
107 case S_IFREG: { 107 case S_IFREG: {
108 /* Regular file */ 108 /* Regular file */
109 char *dst_name;
109 int flags = O_WRONLY | O_CREAT | O_EXCL; 110 int flags = O_WRONLY | O_CREAT | O_EXCL;
110 if (archive_handle->ah_flags & ARCHIVE_O_TRUNC) 111 if (archive_handle->ah_flags & ARCHIVE_O_TRUNC)
111 flags = O_WRONLY | O_CREAT | O_TRUNC; 112 flags = O_WRONLY | O_CREAT | O_TRUNC;
112 dst_fd = xopen3(file_header->name, 113 dst_name = file_header->name;
114#ifdef ARCHIVE_REPLACE_VIA_RENAME
115 if (archive_handle->ah_flags & ARCHIVE_REPLACE_VIA_RENAME)
116 /* rpm-style temp file name */
117 dst_name = xasprintf("%s;%x", dst_name, (int)getpid());
118#endif
119 dst_fd = xopen3(dst_name,
113 flags, 120 flags,
114 file_header->mode 121 file_header->mode
115 ); 122 );
116 bb_copyfd_exact_size(archive_handle->src_fd, dst_fd, file_header->size); 123 bb_copyfd_exact_size(archive_handle->src_fd, dst_fd, file_header->size);
117 close(dst_fd); 124 close(dst_fd);
125#ifdef ARCHIVE_REPLACE_VIA_RENAME
126 if (archive_handle->ah_flags & ARCHIVE_REPLACE_VIA_RENAME) {
127 xrename(dst_name, file_header->name);
128 free(dst_name);
129 }
130#endif
118 break; 131 break;
119 } 132 }
120 case S_IFDIR: 133 case S_IFDIR:
diff --git a/archival/libarchive/decompress_unlzma.c b/archival/libarchive/decompress_unlzma.c
index cfde8ea56..ca32bd82c 100644
--- a/archival/libarchive/decompress_unlzma.c
+++ b/archival/libarchive/decompress_unlzma.c
@@ -45,16 +45,16 @@ typedef struct {
45#define RC_MODEL_TOTAL_BITS 11 45#define RC_MODEL_TOTAL_BITS 11
46 46
47 47
48/* Called twice: once at startup (LZMA_FAST only) and once in rc_normalize() */ 48/* Called once in rc_do_normalize() */
49static size_inline void rc_read(rc_t *rc) 49static void rc_read(rc_t *rc)
50{ 50{
51 int buffer_size = safe_read(rc->fd, RC_BUFFER, RC_BUFFER_SIZE); 51 int buffer_size = safe_read(rc->fd, RC_BUFFER, RC_BUFFER_SIZE);
52//TODO: return -1 instead 52//TODO: return -1 instead
53//This will make unlzma delete broken unpacked file on unpack errors 53//This will make unlzma delete broken unpacked file on unpack errors
54 if (buffer_size <= 0) 54 if (buffer_size <= 0)
55 bb_error_msg_and_die("unexpected EOF"); 55 bb_error_msg_and_die("unexpected EOF");
56 rc->ptr = RC_BUFFER;
57 rc->buffer_end = RC_BUFFER + buffer_size; 56 rc->buffer_end = RC_BUFFER + buffer_size;
57 rc->ptr = RC_BUFFER;
58} 58}
59 59
60/* Called twice, but one callsite is in speed_inline'd rc_is_bit_1() */ 60/* Called twice, but one callsite is in speed_inline'd rc_is_bit_1() */
@@ -65,6 +65,12 @@ static void rc_do_normalize(rc_t *rc)
65 rc->range <<= 8; 65 rc->range <<= 8;
66 rc->code = (rc->code << 8) | *rc->ptr++; 66 rc->code = (rc->code << 8) | *rc->ptr++;
67} 67}
68static ALWAYS_INLINE void rc_normalize(rc_t *rc)
69{
70 if (rc->range < (1 << RC_TOP_BITS)) {
71 rc_do_normalize(rc);
72 }
73}
68 74
69/* Called once */ 75/* Called once */
70static ALWAYS_INLINE rc_t* rc_init(int fd) /*, int buffer_size) */ 76static ALWAYS_INLINE rc_t* rc_init(int fd) /*, int buffer_size) */
@@ -78,15 +84,9 @@ static ALWAYS_INLINE rc_t* rc_init(int fd) /*, int buffer_size) */
78 /* rc->ptr = rc->buffer_end; */ 84 /* rc->ptr = rc->buffer_end; */
79 85
80 for (i = 0; i < 5; i++) { 86 for (i = 0; i < 5; i++) {
81#if ENABLE_FEATURE_LZMA_FAST
82 if (rc->ptr >= rc->buffer_end)
83 rc_read(rc);
84 rc->code = (rc->code << 8) | *rc->ptr++;
85#else
86 rc_do_normalize(rc); 87 rc_do_normalize(rc);
87#endif
88 } 88 }
89 rc->range = 0xFFFFFFFF; 89 rc->range = 0xffffffff;
90 return rc; 90 return rc;
91} 91}
92 92
@@ -96,13 +96,6 @@ static ALWAYS_INLINE void rc_free(rc_t *rc)
96 free(rc); 96 free(rc);
97} 97}
98 98
99static ALWAYS_INLINE void rc_normalize(rc_t *rc)
100{
101 if (rc->range < (1 << RC_TOP_BITS)) {
102 rc_do_normalize(rc);
103 }
104}
105
106/* rc_is_bit_1 is called 9 times */ 99/* rc_is_bit_1 is called 9 times */
107static speed_inline int rc_is_bit_1(rc_t *rc, uint16_t *p) 100static speed_inline int rc_is_bit_1(rc_t *rc, uint16_t *p)
108{ 101{
@@ -120,7 +113,7 @@ static speed_inline int rc_is_bit_1(rc_t *rc, uint16_t *p)
120} 113}
121 114
122/* Called 4 times in unlzma loop */ 115/* Called 4 times in unlzma loop */
123static speed_inline int rc_get_bit(rc_t *rc, uint16_t *p, int *symbol) 116static ALWAYS_INLINE int rc_get_bit(rc_t *rc, uint16_t *p, int *symbol)
124{ 117{
125 int ret = rc_is_bit_1(rc, p); 118 int ret = rc_is_bit_1(rc, p);
126 *symbol = *symbol * 2 + ret; 119 *symbol = *symbol * 2 + ret;
diff --git a/archival/libarchive/decompress_unxz.c b/archival/libarchive/decompress_unxz.c
index 79b48a152..986b7b191 100644
--- a/archival/libarchive/decompress_unxz.c
+++ b/archival/libarchive/decompress_unxz.c
@@ -30,8 +30,8 @@ static uint32_t xz_crc32(const uint8_t *buf, size_t size, uint32_t crc)
30/* We use arch-optimized unaligned accessors */ 30/* We use arch-optimized unaligned accessors */
31#define get_unaligned_le32(buf) ({ uint32_t v; move_from_unaligned32(v, buf); SWAP_LE32(v); }) 31#define get_unaligned_le32(buf) ({ uint32_t v; move_from_unaligned32(v, buf); SWAP_LE32(v); })
32#define get_unaligned_be32(buf) ({ uint32_t v; move_from_unaligned32(v, buf); SWAP_BE32(v); }) 32#define get_unaligned_be32(buf) ({ uint32_t v; move_from_unaligned32(v, buf); SWAP_BE32(v); })
33#define put_unaligned_le32(val, buf) move_to_unaligned16(buf, SWAP_LE32(val)) 33#define put_unaligned_le32(val, buf) move_to_unaligned32(buf, SWAP_LE32(val))
34#define put_unaligned_be32(val, buf) move_to_unaligned16(buf, SWAP_BE32(val)) 34#define put_unaligned_be32(val, buf) move_to_unaligned32(buf, SWAP_BE32(val))
35 35
36#include "unxz/xz_dec_bcj.c" 36#include "unxz/xz_dec_bcj.c"
37#include "unxz/xz_dec_lzma2.c" 37#include "unxz/xz_dec_lzma2.c"
@@ -40,6 +40,7 @@ static uint32_t xz_crc32(const uint8_t *buf, size_t size, uint32_t crc)
40IF_DESKTOP(long long) int FAST_FUNC 40IF_DESKTOP(long long) int FAST_FUNC
41unpack_xz_stream(transformer_aux_data_t *aux, int src_fd, int dst_fd) 41unpack_xz_stream(transformer_aux_data_t *aux, int src_fd, int dst_fd)
42{ 42{
43 enum xz_ret xz_result;
43 struct xz_buf iobuf; 44 struct xz_buf iobuf;
44 struct xz_dec *state; 45 struct xz_dec *state;
45 unsigned char *membuf; 46 unsigned char *membuf;
@@ -63,9 +64,8 @@ unpack_xz_stream(transformer_aux_data_t *aux, int src_fd, int dst_fd)
63 /* Limit memory usage to about 64 MiB. */ 64 /* Limit memory usage to about 64 MiB. */
64 state = xz_dec_init(XZ_DYNALLOC, 64*1024*1024); 65 state = xz_dec_init(XZ_DYNALLOC, 64*1024*1024);
65 66
67 xz_result = X_OK;
66 while (1) { 68 while (1) {
67 enum xz_ret r;
68
69 if (iobuf.in_pos == iobuf.in_size) { 69 if (iobuf.in_pos == iobuf.in_size) {
70 int rd = safe_read(src_fd, membuf, BUFSIZ); 70 int rd = safe_read(src_fd, membuf, BUFSIZ);
71 if (rd < 0) { 71 if (rd < 0) {
@@ -73,28 +73,57 @@ unpack_xz_stream(transformer_aux_data_t *aux, int src_fd, int dst_fd)
73 total = -1; 73 total = -1;
74 break; 74 break;
75 } 75 }
76 if (rd == 0 && xz_result == XZ_STREAM_END)
77 break;
76 iobuf.in_size = rd; 78 iobuf.in_size = rd;
77 iobuf.in_pos = 0; 79 iobuf.in_pos = 0;
78 } 80 }
81 if (xz_result == XZ_STREAM_END) {
82 /*
83 * Try to start decoding next concatenated stream.
84 * Stream padding must always be a multiple of four
85 * bytes to preserve four-byte alignment. To keep the
86 * code slightly smaller, we aren't as strict here as
87 * the .xz spec requires. We just skip all zero-bytes
88 * without checking the alignment and thus can accept
89 * files that aren't valid, e.g. the XZ utils test
90 * files bad-0pad-empty.xz and bad-0catpad-empty.xz.
91 */
92 do {
93 if (membuf[iobuf.in_pos] != 0) {
94 xz_dec_reset(state);
95 goto do_run;
96 }
97 iobuf.in_pos++;
98 } while (iobuf.in_pos < iobuf.in_size);
99 }
100 do_run:
79// bb_error_msg(">in pos:%d size:%d out pos:%d size:%d", 101// bb_error_msg(">in pos:%d size:%d out pos:%d size:%d",
80// iobuf.in_pos, iobuf.in_size, iobuf.out_pos, iobuf.out_size); 102// iobuf.in_pos, iobuf.in_size, iobuf.out_pos, iobuf.out_size);
81 r = xz_dec_run(state, &iobuf); 103 xz_result = xz_dec_run(state, &iobuf);
82// bb_error_msg("<in pos:%d size:%d out pos:%d size:%d r:%d", 104// bb_error_msg("<in pos:%d size:%d out pos:%d size:%d r:%d",
83// iobuf.in_pos, iobuf.in_size, iobuf.out_pos, iobuf.out_size, r); 105// iobuf.in_pos, iobuf.in_size, iobuf.out_pos, iobuf.out_size, xz_result);
84 if (iobuf.out_pos) { 106 if (iobuf.out_pos) {
85 xwrite(dst_fd, iobuf.out, iobuf.out_pos); 107 xwrite(dst_fd, iobuf.out, iobuf.out_pos);
86 IF_DESKTOP(total += iobuf.out_pos;) 108 IF_DESKTOP(total += iobuf.out_pos;)
87 iobuf.out_pos = 0; 109 iobuf.out_pos = 0;
88 } 110 }
89 if (r == XZ_STREAM_END) { 111 if (xz_result == XZ_STREAM_END) {
90 break; 112 /*
113 * Can just "break;" here, if not for concatenated
114 * .xz streams.
115 * Checking for padding may require buffer
116 * replenishment. Can't do it here.
117 */
118 continue;
91 } 119 }
92 if (r != XZ_OK && r != XZ_UNSUPPORTED_CHECK) { 120 if (xz_result != XZ_OK && xz_result != XZ_UNSUPPORTED_CHECK) {
93 bb_error_msg("corrupted data"); 121 bb_error_msg("corrupted data");
94 total = -1; 122 total = -1;
95 break; 123 break;
96 } 124 }
97 } 125 }
126
98 xz_dec_end(state); 127 xz_dec_end(state);
99 free(membuf); 128 free(membuf);
100 129
diff --git a/archival/libarchive/open_transformer.c b/archival/libarchive/open_transformer.c
index f2edc2a2b..841e9dce9 100644
--- a/archival/libarchive/open_transformer.c
+++ b/archival/libarchive/open_transformer.c
@@ -35,6 +35,7 @@ void check_errors_in_children(int signo)
35 if (!signo) { 35 if (!signo) {
36 /* block waiting for any child */ 36 /* block waiting for any child */
37 if (wait(&status) < 0) 37 if (wait(&status) < 0)
38//FIXME: check EINTR?
38 return; /* probably there are no children */ 39 return; /* probably there are no children */
39 goto check_status; 40 goto check_status;
40 } 41 }
@@ -42,14 +43,18 @@ void check_errors_in_children(int signo)
42 /* Wait for any child without blocking */ 43 /* Wait for any child without blocking */
43 for (;;) { 44 for (;;) {
44 if (wait_any_nohang(&status) < 0) 45 if (wait_any_nohang(&status) < 0)
46//FIXME: check EINTR?
45 /* wait failed?! I'm confused... */ 47 /* wait failed?! I'm confused... */
46 return; 48 return;
47 check_status: 49 check_status:
48 if (WIFEXITED(status) && WEXITSTATUS(status) == 0) 50 /*if (WIFEXITED(status) && WEXITSTATUS(status) == 0)*/
51 /* On Linux, the above can be checked simply as: */
52 if (status == 0)
49 /* this child exited with 0 */ 53 /* this child exited with 0 */
50 continue; 54 continue;
51 /* Cannot happen? 55 /* Cannot happen:
52 if (!WIFSIGNALED(status) && !WIFEXITED(status)) ???; */ 56 if (!WIFSIGNALED(status) && !WIFEXITED(status)) ???;
57 */
53 bb_got_signal = 1; 58 bb_got_signal = 1;
54 } 59 }
55} 60}
diff --git a/archival/libarchive/unxz/README b/archival/libarchive/unxz/README
index c5972f6b8..a84912035 100644
--- a/archival/libarchive/unxz/README
+++ b/archival/libarchive/unxz/README
@@ -7,7 +7,7 @@ XZ Embedded
7 7
8 XZ Embedded was written for use in the Linux kernel, but the code can 8 XZ Embedded was written for use in the Linux kernel, but the code can
9 be easily used in other environments too, including regular userspace 9 be easily used in other environments too, including regular userspace
10 applications. 10 applications. See userspace/xzminidec.c for an example program.
11 11
12 This README contains information that is useful only when the copy 12 This README contains information that is useful only when the copy
13 of XZ Embedded isn't part of the Linux kernel tree. You should also 13 of XZ Embedded isn't part of the Linux kernel tree. You should also
@@ -55,7 +55,7 @@ Compiler requirements
55 code is modified not to support large files, which needs some more 55 code is modified not to support large files, which needs some more
56 care than just using 32-bit integer instead of 64-bit). 56 care than just using 32-bit integer instead of 64-bit).
57 57
58 If you use GCC, try to use a recent version. For example, on x86, 58 If you use GCC, try to use a recent version. For example, on x86-32,
59 xz_dec_lzma2.c compiled with GCC 3.3.6 is 15-25 % slower than when 59 xz_dec_lzma2.c compiled with GCC 3.3.6 is 15-25 % slower than when
60 compiled with GCC 4.3.3. 60 compiled with GCC 4.3.3.
61 61
@@ -93,7 +93,7 @@ BCJ filter support
93 them always #defined doesn't hurt either. 93 them always #defined doesn't hurt either.
94 94
95 #define Instruction set BCJ filter endianness 95 #define Instruction set BCJ filter endianness
96 XZ_DEC_X86 x86 or x86-64 Little endian only 96 XZ_DEC_X86 x86-32 or x86-64 Little endian only
97 XZ_DEC_POWERPC PowerPC Big endian only 97 XZ_DEC_POWERPC PowerPC Big endian only
98 XZ_DEC_IA64 Itanium (IA-64) Big or little endian 98 XZ_DEC_IA64 Itanium (IA-64) Big or little endian
99 XZ_DEC_ARM ARM Little endian only 99 XZ_DEC_ARM ARM Little endian only
diff --git a/archival/libarchive/unxz/xz.h b/archival/libarchive/unxz/xz.h
index c6c071c4a..e0b22db56 100644
--- a/archival/libarchive/unxz/xz.h
+++ b/archival/libarchive/unxz/xz.h
@@ -19,6 +19,10 @@
19# include <stdint.h> 19# include <stdint.h>
20#endif 20#endif
21 21
22#ifdef __cplusplus
23extern "C" {
24#endif
25
22/* In Linux, this is used to make extern functions static when needed. */ 26/* In Linux, this is used to make extern functions static when needed. */
23#ifndef XZ_EXTERN 27#ifndef XZ_EXTERN
24# define XZ_EXTERN extern 28# define XZ_EXTERN extern
@@ -70,7 +74,7 @@ enum xz_mode {
70 * @XZ_UNSUPPORTED_CHECK: Integrity check type is not supported. Decoding 74 * @XZ_UNSUPPORTED_CHECK: Integrity check type is not supported. Decoding
71 * is still possible in multi-call mode by simply 75 * is still possible in multi-call mode by simply
72 * calling xz_dec_run() again. 76 * calling xz_dec_run() again.
73 * NOTE: This return value is used only if 77 * Note that this return value is used only if
74 * XZ_DEC_ANY_CHECK was defined at build time, 78 * XZ_DEC_ANY_CHECK was defined at build time,
75 * which is not used in the kernel. Unsupported 79 * which is not used in the kernel. Unsupported
76 * check types return XZ_OPTIONS_ERROR if 80 * check types return XZ_OPTIONS_ERROR if
@@ -105,7 +109,7 @@ enum xz_mode {
105 * stream that is truncated or otherwise corrupt. 109 * stream that is truncated or otherwise corrupt.
106 * 110 *
107 * In single-call mode, XZ_BUF_ERROR is returned only when the output buffer 111 * In single-call mode, XZ_BUF_ERROR is returned only when the output buffer
108 * is too small, or the compressed input is corrupt in a way that makes the 112 * is too small or the compressed input is corrupt in a way that makes the
109 * decoder produce more output than the caller expected. When it is 113 * decoder produce more output than the caller expected. When it is
110 * (relatively) clear that the compressed input is truncated, XZ_DATA_ERROR 114 * (relatively) clear that the compressed input is truncated, XZ_DATA_ERROR
111 * is used instead of XZ_BUF_ERROR. 115 * is used instead of XZ_BUF_ERROR.
@@ -207,8 +211,8 @@ XZ_EXTERN struct xz_dec * XZ_FUNC xz_dec_init(
207 * The possible return values depend on build options and operation mode. 211 * The possible return values depend on build options and operation mode.
208 * See enum xz_ret for details. 212 * See enum xz_ret for details.
209 * 213 *
210 * NOTE: If an error occurs in single-call mode (return value is not 214 * Note that if an error occurs in single-call mode (return value is not
211 * XZ_STREAM_END), b->in_pos and b->out_pos are not modified, and the 215 * XZ_STREAM_END), b->in_pos and b->out_pos are not modified and the
212 * contents of the output buffer from b->out[b->out_pos] onward are 216 * contents of the output buffer from b->out[b->out_pos] onward are
213 * undefined. This is true even after XZ_BUF_ERROR, because with some filter 217 * undefined. This is true even after XZ_BUF_ERROR, because with some filter
214 * chains, there may be a second pass over the output buffer, and this pass 218 * chains, there may be a second pass over the output buffer, and this pass
@@ -268,4 +272,9 @@ XZ_EXTERN void XZ_FUNC xz_crc32_init(void);
268XZ_EXTERN uint32_t XZ_FUNC xz_crc32( 272XZ_EXTERN uint32_t XZ_FUNC xz_crc32(
269 const uint8_t *buf, size_t size, uint32_t crc); 273 const uint8_t *buf, size_t size, uint32_t crc);
270#endif 274#endif
275
276#ifdef __cplusplus
277}
278#endif
279
271#endif 280#endif
diff --git a/archival/libarchive/unxz/xz_dec_bcj.c b/archival/libarchive/unxz/xz_dec_bcj.c
index 09162b51f..e0f913a94 100644
--- a/archival/libarchive/unxz/xz_dec_bcj.c
+++ b/archival/libarchive/unxz/xz_dec_bcj.c
@@ -77,10 +77,13 @@ struct xz_dec_bcj {
77 77
78#ifdef XZ_DEC_X86 78#ifdef XZ_DEC_X86
79/* 79/*
80 * This is macro used to test the most significant byte of a memory address 80 * This is used to test the most significant byte of a memory address
81 * in an x86 instruction. 81 * in an x86 instruction.
82 */ 82 */
83#define bcj_x86_test_msbyte(b) ((b) == 0x00 || (b) == 0xFF) 83static inline int bcj_x86_test_msbyte(uint8_t b)
84{
85 return b == 0x00 || b == 0xFF;
86}
84 87
85static noinline_for_stack size_t XZ_FUNC bcj_x86( 88static noinline_for_stack size_t XZ_FUNC bcj_x86(
86 struct xz_dec_bcj *s, uint8_t *buf, size_t size) 89 struct xz_dec_bcj *s, uint8_t *buf, size_t size)
@@ -443,8 +446,12 @@ XZ_EXTERN enum xz_ret XZ_FUNC xz_dec_bcj_run(struct xz_dec_bcj *s,
443 * next filter in the chain. Apply the BCJ filter on the new data 446 * next filter in the chain. Apply the BCJ filter on the new data
444 * in the output buffer. If everything cannot be filtered, copy it 447 * in the output buffer. If everything cannot be filtered, copy it
445 * to temp and rewind the output buffer position accordingly. 448 * to temp and rewind the output buffer position accordingly.
449 *
450 * This needs to be always run when temp.size == 0 to handle a special
451 * case where the output buffer is full and the next filter has no
452 * more output coming but hasn't returned XZ_STREAM_END yet.
446 */ 453 */
447 if (s->temp.size < b->out_size - b->out_pos) { 454 if (s->temp.size < b->out_size - b->out_pos || s->temp.size == 0) {
448 out_start = b->out_pos; 455 out_start = b->out_pos;
449 memcpy(b->out + b->out_pos, s->temp.buf, s->temp.size); 456 memcpy(b->out + b->out_pos, s->temp.buf, s->temp.size);
450 b->out_pos += s->temp.size; 457 b->out_pos += s->temp.size;
@@ -467,16 +474,25 @@ XZ_EXTERN enum xz_ret XZ_FUNC xz_dec_bcj_run(struct xz_dec_bcj *s,
467 s->temp.size = b->out_pos - out_start; 474 s->temp.size = b->out_pos - out_start;
468 b->out_pos -= s->temp.size; 475 b->out_pos -= s->temp.size;
469 memcpy(s->temp.buf, b->out + b->out_pos, s->temp.size); 476 memcpy(s->temp.buf, b->out + b->out_pos, s->temp.size);
477
478 /*
479 * If there wasn't enough input to the next filter to fill
480 * the output buffer with unfiltered data, there's no point
481 * to try decoding more data to temp.
482 */
483 if (b->out_pos + s->temp.size < b->out_size)
484 return XZ_OK;
470 } 485 }
471 486
472 /* 487 /*
473 * If we have unfiltered data in temp, try to fill by decoding more 488 * We have unfiltered data in temp. If the output buffer isn't full
474 * data from the next filter. Apply the BCJ filter on temp. Then we 489 * yet, try to fill the temp buffer by decoding more data from the
475 * hopefully can fill the actual output buffer by copying filtered 490 * next filter. Apply the BCJ filter on temp. Then we hopefully can
476 * data from temp. A mix of filtered and unfiltered data may be left 491 * fill the actual output buffer by copying filtered data from temp.
477 * in temp; it will be taken care on the next call to this function. 492 * A mix of filtered and unfiltered data may be left in temp; it will
493 * be taken care on the next call to this function.
478 */ 494 */
479 if (s->temp.size > 0) { 495 if (b->out_pos < b->out_size) {
480 /* Make b->out{,_pos,_size} temporarily point to s->temp. */ 496 /* Make b->out{,_pos,_size} temporarily point to s->temp. */
481 s->out = b->out; 497 s->out = b->out;
482 s->out_pos = b->out_pos; 498 s->out_pos = b->out_pos;
diff --git a/archival/libarchive/unxz/xz_dec_lzma2.c b/archival/libarchive/unxz/xz_dec_lzma2.c
index da71cb4d4..3c2dc88b7 100644
--- a/archival/libarchive/unxz/xz_dec_lzma2.c
+++ b/archival/libarchive/unxz/xz_dec_lzma2.c
@@ -407,7 +407,6 @@ static void XZ_FUNC dict_uncompressed(
407 407
408 b->out_pos += copy_size; 408 b->out_pos += copy_size;
409 b->in_pos += copy_size; 409 b->in_pos += copy_size;
410
411 } 410 }
412} 411}
413 412
@@ -972,6 +971,9 @@ XZ_EXTERN NOINLINE enum xz_ret XZ_FUNC xz_dec_lzma2_run(
972 */ 971 */
973 tmp = b->in[b->in_pos++]; 972 tmp = b->in[b->in_pos++];
974 973
974 if (tmp == 0x00)
975 return XZ_STREAM_END;
976
975 if (tmp >= 0xE0 || tmp == 0x01) { 977 if (tmp >= 0xE0 || tmp == 0x01) {
976 s->lzma2.need_props = true; 978 s->lzma2.need_props = true;
977 s->lzma2.need_dict_reset = false; 979 s->lzma2.need_dict_reset = false;
@@ -1004,9 +1006,6 @@ XZ_EXTERN NOINLINE enum xz_ret XZ_FUNC xz_dec_lzma2_run(
1004 lzma_reset(s); 1006 lzma_reset(s);
1005 } 1007 }
1006 } else { 1008 } else {
1007 if (tmp == 0x00)
1008 return XZ_STREAM_END;
1009
1010 if (tmp > 0x02) 1009 if (tmp > 0x02)
1011 return XZ_DATA_ERROR; 1010 return XZ_DATA_ERROR;
1012 1011
diff --git a/archival/libarchive/unxz/xz_stream.h b/archival/libarchive/unxz/xz_stream.h
index 36f2a7cbf..66cb5a705 100644
--- a/archival/libarchive/unxz/xz_stream.h
+++ b/archival/libarchive/unxz/xz_stream.h
@@ -25,15 +25,20 @@
25 25
26#define STREAM_HEADER_SIZE 12 26#define STREAM_HEADER_SIZE 12
27 27
28#define HEADER_MAGIC "\3757zXZ\0" 28#define HEADER_MAGIC "\3757zXZ"
29#define HEADER_MAGIC_SIZE 6 29#define HEADER_MAGIC_SIZE 6
30 30
31#define FOOTER_MAGIC "YZ" 31#define FOOTER_MAGIC "YZ"
32#define FOOTER_MAGIC_SIZE 2 32#define FOOTER_MAGIC_SIZE 2
33 33
34/* 34/*
35 * Variable-length integer can hold a 63-bit unsigned integer, or a special 35 * Variable-length integer can hold a 63-bit unsigned integer or a special
36 * value to indicate that the value is unknown. 36 * value indicating that the value is unknown.
37 *
38 * Experimental: vli_type can be defined to uint32_t to save a few bytes
39 * in code size (no effect on speed). Doing so limits the uncompressed and
40 * compressed size of the file to less than 256 MiB and may also weaken
41 * error detection slightly.
37 */ 42 */
38typedef uint64_t vli_type; 43typedef uint64_t vli_type;
39 44