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 |
