diff options
author | Ron Yorston <rmy@pobox.com> | 2013-03-19 11:18:39 +0000 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2013-03-19 11:18:39 +0000 |
commit | 63d2c5fead323df5f4250ed544d0bc03527c8936 (patch) | |
tree | 660979b139a4bc4b143c08843cb7efbc69bdcb4d /archival/libarchive | |
parent | 27fc2d535588728ac3ca69337271471fb6fe3ee9 (diff) | |
parent | a42f530e034b673726a91ea5d8202254e677f066 (diff) | |
download | busybox-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.c | 15 | ||||
-rw-r--r-- | archival/libarchive/decompress_unlzma.c | 29 | ||||
-rw-r--r-- | archival/libarchive/decompress_unxz.c | 47 | ||||
-rw-r--r-- | archival/libarchive/open_transformer.c | 11 | ||||
-rw-r--r-- | archival/libarchive/unxz/README | 6 | ||||
-rw-r--r-- | archival/libarchive/unxz/xz.h | 17 | ||||
-rw-r--r-- | archival/libarchive/unxz/xz_dec_bcj.c | 34 | ||||
-rw-r--r-- | archival/libarchive/unxz/xz_dec_lzma2.c | 7 | ||||
-rw-r--r-- | archival/libarchive/unxz/xz_stream.h | 11 |
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() */ |
49 | static size_inline void rc_read(rc_t *rc) | 49 | static 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 | } |
68 | static 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 */ |
70 | static ALWAYS_INLINE rc_t* rc_init(int fd) /*, int buffer_size) */ | 76 | static 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 | ||
99 | static 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 */ |
107 | static speed_inline int rc_is_bit_1(rc_t *rc, uint16_t *p) | 100 | static 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 */ |
123 | static speed_inline int rc_get_bit(rc_t *rc, uint16_t *p, int *symbol) | 116 | static 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) | |||
40 | IF_DESKTOP(long long) int FAST_FUNC | 40 | IF_DESKTOP(long long) int FAST_FUNC |
41 | unpack_xz_stream(transformer_aux_data_t *aux, int src_fd, int dst_fd) | 41 | unpack_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 | ||
23 | extern "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); | |||
268 | XZ_EXTERN uint32_t XZ_FUNC xz_crc32( | 272 | XZ_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) | 83 | static inline int bcj_x86_test_msbyte(uint8_t b) |
84 | { | ||
85 | return b == 0x00 || b == 0xFF; | ||
86 | } | ||
84 | 87 | ||
85 | static noinline_for_stack size_t XZ_FUNC bcj_x86( | 88 | static 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 | */ |
38 | typedef uint64_t vli_type; | 43 | typedef uint64_t vli_type; |
39 | 44 | ||