diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2010-06-01 14:41:39 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2010-06-01 14:41:39 +0200 |
commit | 716f3f612e62c55edd052b505a86e4e2e09074a5 (patch) | |
tree | b930509d157cdf4fb3d80fb2633d3da500eb8e90 | |
parent | 11bcf4b22449d08b61617183c1951db98457653a (diff) | |
download | busybox-w32-716f3f612e62c55edd052b505a86e4e2e09074a5.tar.gz busybox-w32-716f3f612e62c55edd052b505a86e4e2e09074a5.tar.bz2 busybox-w32-716f3f612e62c55edd052b505a86e4e2e09074a5.zip |
decompress_unxz: newer version, one which can unpack SHA-256 protected files
function old new delta
check_sizes - 16 +16
crc32_table - 4 +4
index_update 47 40 -7
crc32_validate 110 93 -17
dec_vli 197 165 -32
unpack_xz_stream 4284 4014 -270
------------------------------------------------------------------------------
(add/remove: 2/0 grow/shrink: 0/4 up/down: 20/-326) Total: -306 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | archival/libunarchive/decompress_unxz.c | 18 | ||||
-rw-r--r-- | archival/libunarchive/unxz/xz.h | 58 | ||||
-rw-r--r-- | archival/libunarchive/unxz/xz_config.h | 6 | ||||
-rw-r--r-- | archival/libunarchive/unxz/xz_dec_bcj.c | 10 | ||||
-rw-r--r-- | archival/libunarchive/unxz/xz_dec_stream.c | 113 | ||||
-rw-r--r-- | archival/libunarchive/unxz/xz_private.h | 2 | ||||
-rw-r--r-- | archival/libunarchive/unxz/xz_stream.h | 15 |
7 files changed, 154 insertions, 68 deletions
diff --git a/archival/libunarchive/decompress_unxz.c b/archival/libunarchive/decompress_unxz.c index 924a52513..374b76d66 100644 --- a/archival/libunarchive/decompress_unxz.c +++ b/archival/libunarchive/decompress_unxz.c | |||
@@ -16,9 +16,13 @@ | |||
16 | #define XZ_FUNC FAST_FUNC | 16 | #define XZ_FUNC FAST_FUNC |
17 | #define XZ_EXTERN static | 17 | #define XZ_EXTERN static |
18 | 18 | ||
19 | #define xz_crc32_init(table) crc32_filltable(table, /*endian:*/ 0) | 19 | /* Skip check (rather than fail) of unsupported hash functions */ |
20 | static uint32_t xz_crc32(uint32_t *crc32_table, | 20 | #define XZ_DEC_ANY_CHECK 1 |
21 | const uint8_t *buf, size_t size, uint32_t crc) | 21 | |
22 | /* We use our own crc32 function */ | ||
23 | #define XZ_INTERNAL_CRC32 0 | ||
24 | static uint32_t *crc32_table; | ||
25 | static uint32_t xz_crc32(const uint8_t *buf, size_t size, uint32_t crc) | ||
22 | { | 26 | { |
23 | crc = ~crc; | 27 | crc = ~crc; |
24 | 28 | ||
@@ -29,8 +33,8 @@ static uint32_t xz_crc32(uint32_t *crc32_table, | |||
29 | 33 | ||
30 | return ~crc; | 34 | return ~crc; |
31 | } | 35 | } |
32 | #define xz_crc32 xz_crc32 | ||
33 | 36 | ||
37 | /* We use arch-optimized unaligned accessors */ | ||
34 | #define get_unaligned_le32(buf) ({ uint32_t v; move_from_unaligned32(v, buf); SWAP_LE32(v); }) | 38 | #define get_unaligned_le32(buf) ({ uint32_t v; move_from_unaligned32(v, buf); SWAP_LE32(v); }) |
35 | #define get_unaligned_be32(buf) ({ uint32_t v; move_from_unaligned32(v, buf); SWAP_BE32(v); }) | 39 | #define get_unaligned_be32(buf) ({ uint32_t v; move_from_unaligned32(v, buf); SWAP_BE32(v); }) |
36 | #define put_unaligned_le32(val, buf) move_to_unaligned16(buf, SWAP_LE32(val)) | 40 | #define put_unaligned_le32(val, buf) move_to_unaligned16(buf, SWAP_LE32(val)) |
@@ -64,8 +68,10 @@ unpack_xz_stream(int src_fd, int dst_fd) | |||
64 | iobuf.out = membuf + IN_SIZE; | 68 | iobuf.out = membuf + IN_SIZE; |
65 | iobuf.out_size = OUT_SIZE; | 69 | iobuf.out_size = OUT_SIZE; |
66 | 70 | ||
71 | if (!crc32_table) | ||
72 | crc32_table = crc32_filltable(NULL, /*endian:*/ 0); | ||
73 | |||
67 | state = xz_dec_init(64*1024); /* initial dict of 64k */ | 74 | state = xz_dec_init(64*1024); /* initial dict of 64k */ |
68 | xz_crc32_init(state->crc32_table); | ||
69 | 75 | ||
70 | while (1) { | 76 | while (1) { |
71 | enum xz_ret r; | 77 | enum xz_ret r; |
@@ -102,7 +108,7 @@ unpack_xz_stream(int src_fd, int dst_fd) | |||
102 | ) { | 108 | ) { |
103 | break; | 109 | break; |
104 | } | 110 | } |
105 | if (r != XZ_OK) { | 111 | if (r != XZ_OK && r != XZ_UNSUPPORTED_CHECK) { |
106 | bb_error_msg("corrupted data"); | 112 | bb_error_msg("corrupted data"); |
107 | total = -1; | 113 | total = -1; |
108 | break; | 114 | break; |
diff --git a/archival/libunarchive/unxz/xz.h b/archival/libunarchive/unxz/xz.h index dbb9ba92d..eb82706b9 100644 --- a/archival/libunarchive/unxz/xz.h +++ b/archival/libunarchive/unxz/xz.h | |||
@@ -31,20 +31,29 @@ | |||
31 | 31 | ||
32 | /** | 32 | /** |
33 | * enum xz_ret - Return codes | 33 | * enum xz_ret - Return codes |
34 | * @XZ_OK: Everything is OK so far. More input or more output | 34 | * @XZ_OK: Everything is OK so far. More input or more |
35 | * space is required to continue. | 35 | * output space is required to continue. |
36 | * @XZ_STREAM_END: Operation finished successfully. | 36 | * @XZ_STREAM_END: Operation finished successfully. |
37 | * @XZ_MEMLIMIT_ERROR: Not enough memory was preallocated at decoder | 37 | * @XZ_UNSUPPORTED_CHECK: Integrity check type is not supported. Decoding |
38 | * initialization time. | 38 | * is still possible in multi-call mode by simply |
39 | * @XZ_FORMAT_ERROR: File format was not recognized (wrong magic bytes). | 39 | * calling xz_dec_run() again. |
40 | * @XZ_OPTIONS_ERROR: This implementation doesn't support the requested | 40 | * NOTE: This return value is used only if |
41 | * compression options. In the decoder this means that | 41 | * XZ_DEC_ANY_CHECK was defined at build time, |
42 | * the header CRC32 matches, but the header itself | 42 | * which is not used in the kernel. Unsupported |
43 | * specifies something that we don't support. | 43 | * check types return XZ_OPTIONS_ERROR if |
44 | * @XZ_DATA_ERROR: Compressed data is corrupt. | 44 | * XZ_DEC_ANY_CHECK was not defined at build time. |
45 | * @XZ_BUF_ERROR: Cannot make any progress. Details are slightly | 45 | * @XZ_MEMLIMIT_ERROR: Not enough memory was preallocated at decoder |
46 | * different between multi-call and single-call mode; | 46 | * initialization time. |
47 | * more information below. | 47 | * @XZ_FORMAT_ERROR: File format was not recognized (wrong magic |
48 | * bytes). | ||
49 | * @XZ_OPTIONS_ERROR: This implementation doesn't support the requested | ||
50 | * compression options. In the decoder this means | ||
51 | * that the header CRC32 matches, but the header | ||
52 | * itself specifies something that we don't support. | ||
53 | * @XZ_DATA_ERROR: Compressed data is corrupt. | ||
54 | * @XZ_BUF_ERROR: Cannot make any progress. Details are slightly | ||
55 | * different between multi-call and single-call | ||
56 | * mode; more information below. | ||
48 | * | 57 | * |
49 | * In multi-call mode, XZ_BUF_ERROR is returned when two consecutive calls | 58 | * In multi-call mode, XZ_BUF_ERROR is returned when two consecutive calls |
50 | * to XZ code cannot consume any input and cannot produce any new output. | 59 | * to XZ code cannot consume any input and cannot produce any new output. |
@@ -62,6 +71,7 @@ | |||
62 | enum xz_ret { | 71 | enum xz_ret { |
63 | XZ_OK, | 72 | XZ_OK, |
64 | XZ_STREAM_END, | 73 | XZ_STREAM_END, |
74 | XZ_UNSUPPORTED_CHECK, | ||
65 | XZ_MEMLIMIT_ERROR, | 75 | XZ_MEMLIMIT_ERROR, |
66 | XZ_FORMAT_ERROR, | 76 | XZ_FORMAT_ERROR, |
67 | XZ_OPTIONS_ERROR, | 77 | XZ_OPTIONS_ERROR, |
@@ -129,7 +139,7 @@ struct xz_dec; | |||
129 | * | 139 | * |
130 | * Because the output buffer is used as the workspace, streams encoded using | 140 | * Because the output buffer is used as the workspace, streams encoded using |
131 | * a big dictionary are not a problem in single-call. It is enough that the | 141 | * a big dictionary are not a problem in single-call. It is enough that the |
132 | * output buffer is is big enough to hold the actual uncompressed data; it | 142 | * output buffer is big enough to hold the actual uncompressed data; it |
133 | * can be smaller than the dictionary size stored in the stream headers. | 143 | * can be smaller than the dictionary size stored in the stream headers. |
134 | * | 144 | * |
135 | * On success, xz_dec_init() returns a pointer to struct xz_dec, which is | 145 | * On success, xz_dec_init() returns a pointer to struct xz_dec, which is |
@@ -186,23 +196,27 @@ XZ_EXTERN void XZ_FUNC xz_dec_end(struct xz_dec *s); | |||
186 | * CRC32 module is used instead, and users of this module don't need to | 196 | * CRC32 module is used instead, and users of this module don't need to |
187 | * care about the functions below. | 197 | * care about the functions below. |
188 | */ | 198 | */ |
189 | #if !defined(__KERNEL__) || defined(XZ_INTERNAL_CRC32) | 199 | #ifndef XZ_INTERNAL_CRC32 |
200 | # ifdef __KERNEL__ | ||
201 | # define XZ_INTERNAL_CRC32 0 | ||
202 | # else | ||
203 | # define XZ_INTERNAL_CRC32 1 | ||
204 | # endif | ||
205 | #endif | ||
206 | |||
207 | #if XZ_INTERNAL_CRC32 | ||
190 | /* | 208 | /* |
191 | * This must be called before any other xz_* function to initialize | 209 | * This must be called before any other xz_* function to initialize |
192 | * the CRC32 lookup table. | 210 | * the CRC32 lookup table. |
193 | */ | 211 | */ |
194 | #ifndef xz_crc32_init | 212 | XZ_EXTERN void XZ_FUNC xz_crc32_init(void); |
195 | XZ_EXTERN void XZ_FUNC xz_crc32_init(uint32_t *crc32_table); | ||
196 | #endif | ||
197 | 213 | ||
198 | /* | 214 | /* |
199 | * Update CRC32 value using the polynomial from IEEE-802.3. To start a new | 215 | * Update CRC32 value using the polynomial from IEEE-802.3. To start a new |
200 | * calculation, the third argument must be zero. To continue the calculation, | 216 | * calculation, the third argument must be zero. To continue the calculation, |
201 | * the previously returned value is passed as the third argument. | 217 | * the previously returned value is passed as the third argument. |
202 | */ | 218 | */ |
203 | #ifndef xz_crc32 | 219 | XZ_EXTERN uint32_t XZ_FUNC xz_crc32( |
204 | XZ_EXTERN uint32_t XZ_FUNC xz_crc32(uint32_t *crc32_table, | ||
205 | const uint8_t *buf, size_t size, uint32_t crc); | 220 | const uint8_t *buf, size_t size, uint32_t crc); |
206 | #endif | 221 | #endif |
207 | #endif | 222 | #endif |
208 | #endif | ||
diff --git a/archival/libunarchive/unxz/xz_config.h b/archival/libunarchive/unxz/xz_config.h index 3259815f0..ff90eff26 100644 --- a/archival/libunarchive/unxz/xz_config.h +++ b/archival/libunarchive/unxz/xz_config.h | |||
@@ -43,7 +43,7 @@ | |||
43 | * becomes slow. | 43 | * becomes slow. |
44 | * | 44 | * |
45 | * NOTE: System headers on GNU/Linux may #define this macro already, | 45 | * NOTE: System headers on GNU/Linux may #define this macro already, |
46 | * so if you want to change it, it you need to #undef it first. | 46 | * so if you want to change it, you need to #undef it first. |
47 | */ | 47 | */ |
48 | #ifndef __always_inline | 48 | #ifndef __always_inline |
49 | # ifdef __GNUC__ | 49 | # ifdef __GNUC__ |
@@ -114,6 +114,8 @@ static inline void XZ_FUNC put_unaligned_be32(uint32_t val, uint8_t *buf) | |||
114 | * little endian systems, #define get_le32(ptr) (*(const uint32_t *)(ptr)) | 114 | * little endian systems, #define get_le32(ptr) (*(const uint32_t *)(ptr)) |
115 | * could save a few bytes in code size. | 115 | * could save a few bytes in code size. |
116 | */ | 116 | */ |
117 | #define get_le32 get_unaligned_le32 | 117 | #ifndef get_le32 |
118 | # define get_le32 get_unaligned_le32 | ||
119 | #endif | ||
118 | 120 | ||
119 | #endif | 121 | #endif |
diff --git a/archival/libunarchive/unxz/xz_dec_bcj.c b/archival/libunarchive/unxz/xz_dec_bcj.c index d4b6ef751..09162b51f 100644 --- a/archival/libunarchive/unxz/xz_dec_bcj.c +++ b/archival/libunarchive/unxz/xz_dec_bcj.c | |||
@@ -10,6 +10,12 @@ | |||
10 | 10 | ||
11 | #include "xz_private.h" | 11 | #include "xz_private.h" |
12 | 12 | ||
13 | /* | ||
14 | * The rest of the file is inside this ifdef. It makes things a little more | ||
15 | * convenient when building without support for any BCJ filters. | ||
16 | */ | ||
17 | #ifdef XZ_DEC_BCJ | ||
18 | |||
13 | struct xz_dec_bcj { | 19 | struct xz_dec_bcj { |
14 | /* Type of the BCJ filter being used */ | 20 | /* Type of the BCJ filter being used */ |
15 | enum { | 21 | enum { |
@@ -331,7 +337,6 @@ static noinline_for_stack size_t XZ_FUNC bcj_sparc( | |||
331 | } | 337 | } |
332 | #endif | 338 | #endif |
333 | 339 | ||
334 | #ifdef XZ_DEC_BCJ | ||
335 | /* | 340 | /* |
336 | * Apply the selected BCJ filter. Update *pos and s->pos to match the amount | 341 | * Apply the selected BCJ filter. Update *pos and s->pos to match the amount |
337 | * of data that got filtered. | 342 | * of data that got filtered. |
@@ -388,9 +393,7 @@ static void XZ_FUNC bcj_apply(struct xz_dec_bcj *s, | |||
388 | *pos += filtered; | 393 | *pos += filtered; |
389 | s->pos += filtered; | 394 | s->pos += filtered; |
390 | } | 395 | } |
391 | #endif | ||
392 | 396 | ||
393 | #ifdef XZ_DEC_BCJ | ||
394 | /* | 397 | /* |
395 | * Flush pending filtered data from temp to the output buffer. | 398 | * Flush pending filtered data from temp to the output buffer. |
396 | * Move the remaining mixture of possibly filtered and unfiltered | 399 | * Move the remaining mixture of possibly filtered and unfiltered |
@@ -557,4 +560,5 @@ XZ_EXTERN enum xz_ret XZ_FUNC xz_dec_bcj_reset( | |||
557 | 560 | ||
558 | return XZ_OK; | 561 | return XZ_OK; |
559 | } | 562 | } |
563 | |||
560 | #endif | 564 | #endif |
diff --git a/archival/libunarchive/unxz/xz_dec_stream.c b/archival/libunarchive/unxz/xz_dec_stream.c index 121c3b53a..21db283fb 100644 --- a/archival/libunarchive/unxz/xz_dec_stream.c +++ b/archival/libunarchive/unxz/xz_dec_stream.c | |||
@@ -45,8 +45,8 @@ struct xz_dec { | |||
45 | /* CRC32 value in Block or Index */ | 45 | /* CRC32 value in Block or Index */ |
46 | uint32_t crc32; | 46 | uint32_t crc32; |
47 | 47 | ||
48 | /* True if CRC32 is calculated from uncompressed data */ | 48 | /* Type of the integrity check calculated from uncompressed data */ |
49 | uint8_t crc_type; | 49 | enum xz_check check_type; |
50 | 50 | ||
51 | /* True if we are operating in single-call mode. */ | 51 | /* True if we are operating in single-call mode. */ |
52 | bool single_call; | 52 | bool single_call; |
@@ -134,9 +134,19 @@ struct xz_dec { | |||
134 | struct xz_dec_bcj *bcj; | 134 | struct xz_dec_bcj *bcj; |
135 | bool bcj_active; | 135 | bool bcj_active; |
136 | #endif | 136 | #endif |
137 | }; | ||
137 | 138 | ||
138 | uint32_t crc32_table[256]; | 139 | #ifdef XZ_DEC_ANY_CHECK |
140 | /* Sizes of the Check field with different Check IDs */ | ||
141 | static const uint8_t check_sizes[16] = { | ||
142 | 0, | ||
143 | 4, 4, 4, | ||
144 | 8, 8, 8, | ||
145 | 16, 16, 16, | ||
146 | 32, 32, 32, | ||
147 | 64, 64, 64 | ||
139 | }; | 148 | }; |
149 | #endif | ||
140 | 150 | ||
141 | /* | 151 | /* |
142 | * Fill s->temp by copying data starting from b->in[b->in_pos]. Caller | 152 | * Fill s->temp by copying data starting from b->in[b->in_pos]. Caller |
@@ -231,9 +241,8 @@ static enum xz_ret XZ_FUNC dec_block(struct xz_dec *s, struct xz_buf *b) | |||
231 | > s->block_header.uncompressed) | 241 | > s->block_header.uncompressed) |
232 | return XZ_DATA_ERROR; | 242 | return XZ_DATA_ERROR; |
233 | 243 | ||
234 | if (s->crc_type == 0x01) | 244 | if (s->check_type == XZ_CHECK_CRC32) |
235 | s->crc32 = xz_crc32(s->crc32_table, | 245 | s->crc32 = xz_crc32(b->out + s->out_start, |
236 | b->out + s->out_start, | ||
237 | b->out_pos - s->out_start, s->crc32); | 246 | b->out_pos - s->out_start, s->crc32); |
238 | 247 | ||
239 | if (ret == XZ_STREAM_END) { | 248 | if (ret == XZ_STREAM_END) { |
@@ -249,15 +258,16 @@ static enum xz_ret XZ_FUNC dec_block(struct xz_dec *s, struct xz_buf *b) | |||
249 | 258 | ||
250 | s->block.hash.unpadded += s->block_header.size | 259 | s->block.hash.unpadded += s->block_header.size |
251 | + s->block.compressed; | 260 | + s->block.compressed; |
252 | if (s->crc_type == 0x01) | 261 | |
262 | #ifdef XZ_DEC_ANY_CHECK | ||
263 | s->block.hash.unpadded += check_sizes[s->check_type]; | ||
264 | #else | ||
265 | if (s->check_type == XZ_CHECK_CRC32) | ||
253 | s->block.hash.unpadded += 4; | 266 | s->block.hash.unpadded += 4; |
254 | if (s->crc_type == 0x04) /* CRC64 */ | 267 | #endif |
255 | s->block.hash.unpadded += 8; | ||
256 | if (s->crc_type == 0x0A) /* SHA-256 */ | ||
257 | s->block.hash.unpadded += 32; | ||
258 | 268 | ||
259 | s->block.hash.uncompressed += s->block.uncompressed; | 269 | s->block.hash.uncompressed += s->block.uncompressed; |
260 | s->block.hash.crc32 = xz_crc32(s->crc32_table, | 270 | s->block.hash.crc32 = xz_crc32( |
261 | (const uint8_t *)&s->block.hash, | 271 | (const uint8_t *)&s->block.hash, |
262 | sizeof(s->block.hash), s->block.hash.crc32); | 272 | sizeof(s->block.hash), s->block.hash.crc32); |
263 | 273 | ||
@@ -272,7 +282,7 @@ static void XZ_FUNC index_update(struct xz_dec *s, const struct xz_buf *b) | |||
272 | { | 282 | { |
273 | size_t in_used = b->in_pos - s->in_start; | 283 | size_t in_used = b->in_pos - s->in_start; |
274 | s->index.size += in_used; | 284 | s->index.size += in_used; |
275 | s->crc32 = xz_crc32(s->crc32_table, b->in + s->in_start, in_used, s->crc32); | 285 | s->crc32 = xz_crc32(b->in + s->in_start, in_used, s->crc32); |
276 | } | 286 | } |
277 | 287 | ||
278 | /* | 288 | /* |
@@ -316,7 +326,7 @@ static enum xz_ret XZ_FUNC dec_index(struct xz_dec *s, struct xz_buf *b) | |||
316 | 326 | ||
317 | case SEQ_INDEX_UNCOMPRESSED: | 327 | case SEQ_INDEX_UNCOMPRESSED: |
318 | s->index.hash.uncompressed += s->vli; | 328 | s->index.hash.uncompressed += s->vli; |
319 | s->index.hash.crc32 = xz_crc32(s->crc32_table, | 329 | s->index.hash.crc32 = xz_crc32( |
320 | (const uint8_t *)&s->index.hash, | 330 | (const uint8_t *)&s->index.hash, |
321 | sizeof(s->index.hash), | 331 | sizeof(s->index.hash), |
322 | s->index.hash.crc32); | 332 | s->index.hash.crc32); |
@@ -352,31 +362,58 @@ static enum xz_ret XZ_FUNC crc32_validate(struct xz_dec *s, struct xz_buf *b) | |||
352 | return XZ_STREAM_END; | 362 | return XZ_STREAM_END; |
353 | } | 363 | } |
354 | 364 | ||
365 | #ifdef XZ_DEC_ANY_CHECK | ||
366 | /* | ||
367 | * Skip over the Check field when the Check ID is not supported. | ||
368 | * Returns true once the whole Check field has been skipped over. | ||
369 | */ | ||
370 | static bool XZ_FUNC check_skip(struct xz_dec *s, struct xz_buf *b) | ||
371 | { | ||
372 | while (s->pos < check_sizes[s->check_type]) { | ||
373 | if (b->in_pos == b->in_size) | ||
374 | return false; | ||
375 | |||
376 | ++b->in_pos; | ||
377 | ++s->pos; | ||
378 | } | ||
379 | |||
380 | s->pos = 0; | ||
381 | |||
382 | return true; | ||
383 | } | ||
384 | #endif | ||
385 | |||
355 | /* Decode the Stream Header field (the first 12 bytes of the .xz Stream). */ | 386 | /* Decode the Stream Header field (the first 12 bytes of the .xz Stream). */ |
356 | static enum xz_ret XZ_FUNC dec_stream_header(struct xz_dec *s) | 387 | static enum xz_ret XZ_FUNC dec_stream_header(struct xz_dec *s) |
357 | { | 388 | { |
358 | if (!memeq(s->temp.buf, HEADER_MAGIC, HEADER_MAGIC_SIZE)) | 389 | if (!memeq(s->temp.buf, HEADER_MAGIC, HEADER_MAGIC_SIZE)) |
359 | return XZ_FORMAT_ERROR; | 390 | return XZ_FORMAT_ERROR; |
360 | 391 | ||
361 | if (xz_crc32(s->crc32_table, s->temp.buf + HEADER_MAGIC_SIZE, 2, 0) | 392 | if (xz_crc32(s->temp.buf + HEADER_MAGIC_SIZE, 2, 0) |
362 | != get_le32(s->temp.buf + HEADER_MAGIC_SIZE + 2)) | 393 | != get_le32(s->temp.buf + HEADER_MAGIC_SIZE + 2)) |
363 | return XZ_DATA_ERROR; | 394 | return XZ_DATA_ERROR; |
364 | 395 | ||
396 | if (s->temp.buf[HEADER_MAGIC_SIZE] != 0) | ||
397 | return XZ_OPTIONS_ERROR; | ||
398 | |||
365 | /* | 399 | /* |
366 | * Decode the Stream Flags field. Of integrity checks, we support | 400 | * Of integrity checks, we support only none (Check ID = 0) and |
367 | * only none (Check ID = 0) and CRC32 (Check ID = 1). | 401 | * CRC32 (Check ID = 1). However, if XZ_DEC_ANY_CHECK is defined, |
368 | * We also accept CRC64 and SHA-256, but they will not be verified. | 402 | * we will accept other check types too, but then the check won't |
403 | * be verified and a warning (XZ_UNSUPPORTED_CHECK) will be given. | ||
369 | */ | 404 | */ |
370 | if (s->temp.buf[HEADER_MAGIC_SIZE] != 0 | 405 | s->check_type = s->temp.buf[HEADER_MAGIC_SIZE + 1]; |
371 | || (s->temp.buf[HEADER_MAGIC_SIZE + 1] > 1 | 406 | |
372 | && s->temp.buf[HEADER_MAGIC_SIZE + 1] != 0x04 /* CRC64 */ | 407 | #ifdef XZ_DEC_ANY_CHECK |
373 | && s->temp.buf[HEADER_MAGIC_SIZE + 1] != 0x0A /* SHA-256 */ | 408 | if (s->check_type > XZ_CHECK_MAX) |
374 | ) | ||
375 | ) { | ||
376 | return XZ_OPTIONS_ERROR; | 409 | return XZ_OPTIONS_ERROR; |
377 | } | ||
378 | 410 | ||
379 | s->crc_type = s->temp.buf[HEADER_MAGIC_SIZE + 1]; | 411 | if (s->check_type > XZ_CHECK_CRC32) |
412 | return XZ_UNSUPPORTED_CHECK; | ||
413 | #else | ||
414 | if (s->check_type > XZ_CHECK_CRC32) | ||
415 | return XZ_OPTIONS_ERROR; | ||
416 | #endif | ||
380 | 417 | ||
381 | return XZ_OK; | 418 | return XZ_OK; |
382 | } | 419 | } |
@@ -387,7 +424,7 @@ static enum xz_ret XZ_FUNC dec_stream_footer(struct xz_dec *s) | |||
387 | if (!memeq(s->temp.buf + 10, FOOTER_MAGIC, FOOTER_MAGIC_SIZE)) | 424 | if (!memeq(s->temp.buf + 10, FOOTER_MAGIC, FOOTER_MAGIC_SIZE)) |
388 | return XZ_DATA_ERROR; | 425 | return XZ_DATA_ERROR; |
389 | 426 | ||
390 | if (xz_crc32(s->crc32_table, s->temp.buf + 4, 6, 0) != get_le32(s->temp.buf)) | 427 | if (xz_crc32(s->temp.buf + 4, 6, 0) != get_le32(s->temp.buf)) |
391 | return XZ_DATA_ERROR; | 428 | return XZ_DATA_ERROR; |
392 | 429 | ||
393 | /* | 430 | /* |
@@ -398,7 +435,7 @@ static enum xz_ret XZ_FUNC dec_stream_footer(struct xz_dec *s) | |||
398 | if ((s->index.size >> 2) != get_le32(s->temp.buf + 4)) | 435 | if ((s->index.size >> 2) != get_le32(s->temp.buf + 4)) |
399 | return XZ_DATA_ERROR; | 436 | return XZ_DATA_ERROR; |
400 | 437 | ||
401 | if (s->temp.buf[8] != 0 || s->temp.buf[9] != s->crc_type) | 438 | if (s->temp.buf[8] != 0 || s->temp.buf[9] != s->check_type) |
402 | return XZ_DATA_ERROR; | 439 | return XZ_DATA_ERROR; |
403 | 440 | ||
404 | /* | 441 | /* |
@@ -418,7 +455,7 @@ static enum xz_ret XZ_FUNC dec_block_header(struct xz_dec *s) | |||
418 | * eight bytes so this is safe. | 455 | * eight bytes so this is safe. |
419 | */ | 456 | */ |
420 | s->temp.size -= 4; | 457 | s->temp.size -= 4; |
421 | if (xz_crc32(s->crc32_table, s->temp.buf, s->temp.size, 0) | 458 | if (xz_crc32(s->temp.buf, s->temp.size, 0) |
422 | != get_le32(s->temp.buf + s->temp.size)) | 459 | != get_le32(s->temp.buf + s->temp.size)) |
423 | return XZ_DATA_ERROR; | 460 | return XZ_DATA_ERROR; |
424 | 461 | ||
@@ -533,12 +570,19 @@ static enum xz_ret XZ_FUNC dec_main(struct xz_dec *s, struct xz_buf *b) | |||
533 | if (!fill_temp(s, b)) | 570 | if (!fill_temp(s, b)) |
534 | return XZ_OK; | 571 | return XZ_OK; |
535 | 572 | ||
573 | /* | ||
574 | * If dec_stream_header() returns | ||
575 | * XZ_UNSUPPORTED_CHECK, it is still possible | ||
576 | * to continue decoding if working in multi-call | ||
577 | * mode. Thus, update s->sequence before calling | ||
578 | * dec_stream_header(). | ||
579 | */ | ||
580 | s->sequence = SEQ_BLOCK_START; | ||
581 | |||
536 | ret = dec_stream_header(s); | 582 | ret = dec_stream_header(s); |
537 | if (ret != XZ_OK) | 583 | if (ret != XZ_OK) |
538 | return ret; | 584 | return ret; |
539 | 585 | ||
540 | s->sequence = SEQ_BLOCK_START; | ||
541 | |||
542 | case SEQ_BLOCK_START: | 586 | case SEQ_BLOCK_START: |
543 | /* We need one byte of input to continue. */ | 587 | /* We need one byte of input to continue. */ |
544 | if (b->in_pos == b->in_size) | 588 | if (b->in_pos == b->in_size) |
@@ -600,11 +644,16 @@ static enum xz_ret XZ_FUNC dec_main(struct xz_dec *s, struct xz_buf *b) | |||
600 | s->sequence = SEQ_BLOCK_CHECK; | 644 | s->sequence = SEQ_BLOCK_CHECK; |
601 | 645 | ||
602 | case SEQ_BLOCK_CHECK: | 646 | case SEQ_BLOCK_CHECK: |
603 | if (s->crc_type == 0x01) { | 647 | if (s->check_type == XZ_CHECK_CRC32) { |
604 | ret = crc32_validate(s, b); | 648 | ret = crc32_validate(s, b); |
605 | if (ret != XZ_STREAM_END) | 649 | if (ret != XZ_STREAM_END) |
606 | return ret; | 650 | return ret; |
607 | } | 651 | } |
652 | #ifdef XZ_DEC_ANY_CHECK | ||
653 | else if (!check_skip(s, b)) { | ||
654 | return XZ_OK; | ||
655 | } | ||
656 | #endif | ||
608 | 657 | ||
609 | s->sequence = SEQ_BLOCK_START; | 658 | s->sequence = SEQ_BLOCK_START; |
610 | break; | 659 | break; |
diff --git a/archival/libunarchive/unxz/xz_private.h b/archival/libunarchive/unxz/xz_private.h index 9da8d7061..f4e0b4010 100644 --- a/archival/libunarchive/unxz/xz_private.h +++ b/archival/libunarchive/unxz/xz_private.h | |||
@@ -112,9 +112,9 @@ XZ_EXTERN enum xz_ret XZ_FUNC xz_dec_bcj_reset( | |||
112 | */ | 112 | */ |
113 | XZ_EXTERN enum xz_ret XZ_FUNC xz_dec_bcj_run(struct xz_dec_bcj *s, | 113 | XZ_EXTERN enum xz_ret XZ_FUNC xz_dec_bcj_run(struct xz_dec_bcj *s, |
114 | struct xz_dec_lzma2 *lzma2, struct xz_buf *b); | 114 | struct xz_dec_lzma2 *lzma2, struct xz_buf *b); |
115 | #endif | ||
116 | 115 | ||
117 | /* Free the memory allocated for the BCJ filters. */ | 116 | /* Free the memory allocated for the BCJ filters. */ |
118 | #define xz_dec_bcj_end(s) kfree(s) | 117 | #define xz_dec_bcj_end(s) kfree(s) |
118 | #endif | ||
119 | 119 | ||
120 | #endif | 120 | #endif |
diff --git a/archival/libunarchive/unxz/xz_stream.h b/archival/libunarchive/unxz/xz_stream.h index efbe75ae3..36f2a7cbf 100644 --- a/archival/libunarchive/unxz/xz_stream.h +++ b/archival/libunarchive/unxz/xz_stream.h | |||
@@ -10,10 +10,10 @@ | |||
10 | #ifndef XZ_STREAM_H | 10 | #ifndef XZ_STREAM_H |
11 | #define XZ_STREAM_H | 11 | #define XZ_STREAM_H |
12 | 12 | ||
13 | #if defined(__KERNEL__) && !defined(XZ_INTERNAL_CRC32) | 13 | #if defined(__KERNEL__) && !XZ_INTERNAL_CRC32 |
14 | # include <linux/crc32.h> | 14 | # include <linux/crc32.h> |
15 | # undef crc32 | 15 | # undef crc32 |
16 | # define xz_crc32(crc32_table, buf, size, crc) \ | 16 | # define xz_crc32(buf, size, crc) \ |
17 | (~crc32_le(~(uint32_t)(crc), buf, size)) | 17 | (~crc32_le(~(uint32_t)(crc), buf, size)) |
18 | #endif | 18 | #endif |
19 | 19 | ||
@@ -43,4 +43,15 @@ typedef uint64_t vli_type; | |||
43 | /* Maximum encoded size of a VLI */ | 43 | /* Maximum encoded size of a VLI */ |
44 | #define VLI_BYTES_MAX (sizeof(vli_type) * 8 / 7) | 44 | #define VLI_BYTES_MAX (sizeof(vli_type) * 8 / 7) |
45 | 45 | ||
46 | /* Integrity Check types */ | ||
47 | enum xz_check { | ||
48 | XZ_CHECK_NONE = 0, | ||
49 | XZ_CHECK_CRC32 = 1, | ||
50 | XZ_CHECK_CRC64 = 4, | ||
51 | XZ_CHECK_SHA256 = 10 | ||
52 | }; | ||
53 | |||
54 | /* Maximum possible Check ID */ | ||
55 | #define XZ_CHECK_MAX 15 | ||
56 | |||
46 | #endif | 57 | #endif |