| block_decoder.c | block_decoder.c | |||
|---|---|---|---|---|
| skipping to change at line 47 | skipping to change at line 47 | |||
| /// Maximum allowed Compressed Size; this takes into account the | /// Maximum allowed Compressed Size; this takes into account the | |||
| /// size of the Block Header and Check fields when Compressed Size | /// size of the Block Header and Check fields when Compressed Size | |||
| /// is unknown. | /// is unknown. | |||
| lzma_vli compressed_limit; | lzma_vli compressed_limit; | |||
| /// Position when reading the Check field | /// Position when reading the Check field | |||
| size_t check_pos; | size_t check_pos; | |||
| /// Check of the uncompressed data | /// Check of the uncompressed data | |||
| lzma_check_state check; | lzma_check_state check; | |||
| /// True if the integrity check won't be calculated and verified. | ||||
| bool ignore_check; | ||||
| }; | }; | |||
| static inline bool | static inline bool | |||
| update_size(lzma_vli *size, lzma_vli add, lzma_vli limit) | update_size(lzma_vli *size, lzma_vli add, lzma_vli limit) | |||
| { | { | |||
| if (limit > LZMA_VLI_MAX) | if (limit > LZMA_VLI_MAX) | |||
| limit = LZMA_VLI_MAX; | limit = LZMA_VLI_MAX; | |||
| if (limit < *size || limit - *size < add) | if (limit < *size || limit - *size < add) | |||
| return true; | return true; | |||
| skipping to change at line 70 | skipping to change at line 73 | |||
| return false; | return false; | |||
| } | } | |||
| static inline bool | static inline bool | |||
| is_size_valid(lzma_vli size, lzma_vli reference) | is_size_valid(lzma_vli size, lzma_vli reference) | |||
| { | { | |||
| return reference == LZMA_VLI_UNKNOWN || reference == size; | return reference == LZMA_VLI_UNKNOWN || reference == size; | |||
| } | } | |||
| static lzma_ret | static lzma_ret | |||
| block_decode(lzma_coder *coder, lzma_allocator *allocator, | block_decode(lzma_coder *coder, const lzma_allocator *allocator, | |||
| const uint8_t *restrict in, size_t *restrict in_pos, | const uint8_t *restrict in, size_t *restrict in_pos, | |||
| size_t in_size, uint8_t *restrict out, | size_t in_size, uint8_t *restrict out, | |||
| size_t *restrict out_pos, size_t out_size, lzma_action actio n) | size_t *restrict out_pos, size_t out_size, lzma_action actio n) | |||
| { | { | |||
| switch (coder->sequence) { | switch (coder->sequence) { | |||
| case SEQ_CODE: { | case SEQ_CODE: { | |||
| const size_t in_start = *in_pos; | const size_t in_start = *in_pos; | |||
| const size_t out_start = *out_pos; | const size_t out_start = *out_pos; | |||
| const lzma_ret ret = coder->next.code(coder->next.coder, | const lzma_ret ret = coder->next.code(coder->next.coder, | |||
| skipping to change at line 96 | skipping to change at line 99 | |||
| // NOTE: We compare to compressed_limit here, which prevents | // NOTE: We compare to compressed_limit here, which prevents | |||
| // the total size of the Block growing past LZMA_VLI_MAX. | // the total size of the Block growing past LZMA_VLI_MAX. | |||
| if (update_size(&coder->compressed_size, in_used, | if (update_size(&coder->compressed_size, in_used, | |||
| coder->compressed_limit) | coder->compressed_limit) | |||
| || update_size(&coder->uncompressed_size, | || update_size(&coder->uncompressed_size, | |||
| out_used, | out_used, | |||
| coder->block->uncompressed_size)) | coder->block->uncompressed_size)) | |||
| return LZMA_DATA_ERROR; | return LZMA_DATA_ERROR; | |||
| lzma_check_update(&coder->check, coder->block->check, | if (!coder->ignore_check) | |||
| out + out_start, out_used); | lzma_check_update(&coder->check, coder->block->check | |||
| , | ||||
| out + out_start, out_used); | ||||
| if (ret != LZMA_STREAM_END) | if (ret != LZMA_STREAM_END) | |||
| return ret; | return ret; | |||
| // Compressed and Uncompressed Sizes are now at their final | // Compressed and Uncompressed Sizes are now at their final | |||
| // values. Verify that they match the values given to us. | // values. Verify that they match the values given to us. | |||
| if (!is_size_valid(coder->compressed_size, | if (!is_size_valid(coder->compressed_size, | |||
| coder->block->compressed_size) | coder->block->compressed_size) | |||
| || !is_size_valid(coder->uncompressed_size, | || !is_size_valid(coder->uncompressed_size, | |||
| coder->block->uncompressed_size)) | coder->block->uncompressed_size)) | |||
| skipping to change at line 139 | skipping to change at line 143 | |||
| // us anymore. | // us anymore. | |||
| ++coder->compressed_size; | ++coder->compressed_size; | |||
| if (in[(*in_pos)++] != 0x00) | if (in[(*in_pos)++] != 0x00) | |||
| return LZMA_DATA_ERROR; | return LZMA_DATA_ERROR; | |||
| } | } | |||
| if (coder->block->check == LZMA_CHECK_NONE) | if (coder->block->check == LZMA_CHECK_NONE) | |||
| return LZMA_STREAM_END; | return LZMA_STREAM_END; | |||
| lzma_check_finish(&coder->check, coder->block->check); | if (!coder->ignore_check) | |||
| lzma_check_finish(&coder->check, coder->block->check | ||||
| ); | ||||
| coder->sequence = SEQ_CHECK; | coder->sequence = SEQ_CHECK; | |||
| // Fall through | // Fall through | |||
| case SEQ_CHECK: { | case SEQ_CHECK: { | |||
| const size_t check_size = lzma_check_size(coder->block->chec k); | const size_t check_size = lzma_check_size(coder->block->chec k); | |||
| lzma_bufcpy(in, in_pos, in_size, coder->block->raw_check, | lzma_bufcpy(in, in_pos, in_size, coder->block->raw_check, | |||
| &coder->check_pos, check_size); | &coder->check_pos, check_size); | |||
| if (coder->check_pos < check_size) | if (coder->check_pos < check_size) | |||
| return LZMA_OK; | return LZMA_OK; | |||
| // Validate the Check only if we support it. | // Validate the Check only if we support it. | |||
| // coder->check.buffer may be uninitialized | // coder->check.buffer may be uninitialized | |||
| // when the Check ID is not supported. | // when the Check ID is not supported. | |||
| if (lzma_check_is_supported(coder->block->check) | if (!coder->ignore_check | |||
| && lzma_check_is_supported(coder->block->che | ||||
| ck) | ||||
| && memcmp(coder->block->raw_check, | && memcmp(coder->block->raw_check, | |||
| coder->check.buffer.u8, | coder->check.buffer.u8, | |||
| check_size) != 0) | check_size) != 0) | |||
| return LZMA_DATA_ERROR; | return LZMA_DATA_ERROR; | |||
| return LZMA_STREAM_END; | return LZMA_STREAM_END; | |||
| } | } | |||
| } | } | |||
| return LZMA_PROG_ERROR; | return LZMA_PROG_ERROR; | |||
| } | } | |||
| static void | static void | |||
| block_decoder_end(lzma_coder *coder, lzma_allocator *allocator) | block_decoder_end(lzma_coder *coder, const lzma_allocator *allocator) | |||
| { | { | |||
| lzma_next_end(&coder->next, allocator); | lzma_next_end(&coder->next, allocator); | |||
| lzma_free(coder, allocator); | lzma_free(coder, allocator); | |||
| return; | return; | |||
| } | } | |||
| extern lzma_ret | extern lzma_ret | |||
| lzma_block_decoder_init(lzma_next_coder *next, lzma_allocator *allocator, | lzma_block_decoder_init(lzma_next_coder *next, const lzma_allocator *alloca tor, | |||
| lzma_block *block) | lzma_block *block) | |||
| { | { | |||
| lzma_next_coder_init(&lzma_block_decoder_init, next, allocator); | lzma_next_coder_init(&lzma_block_decoder_init, next, allocator); | |||
| // Validate the options. lzma_block_unpadded_size() does that for us | // Validate the options. lzma_block_unpadded_size() does that for us | |||
| // except for Uncompressed Size and filters. Filters are validated | // except for Uncompressed Size and filters. Filters are validated | |||
| // by the raw decoder. | // by the raw decoder. | |||
| if (lzma_block_unpadded_size(block) == 0 | if (lzma_block_unpadded_size(block) == 0 | |||
| || !lzma_vli_is_valid(block->uncompressed_size)) | || !lzma_vli_is_valid(block->uncompressed_size)) | |||
| return LZMA_PROG_ERROR; | return LZMA_PROG_ERROR; | |||
| skipping to change at line 221 | skipping to change at line 228 | |||
| - block->header_size | - block->header_size | |||
| - lzma_check_size(block->check) | - lzma_check_size(block->check) | |||
| : block->compressed_size; | : block->compressed_size; | |||
| // Initialize the check. It's caller's problem if the Check ID is no t | // Initialize the check. It's caller's problem if the Check ID is no t | |||
| // supported, and the Block decoder cannot verify the Check field. | // supported, and the Block decoder cannot verify the Check field. | |||
| // Caller can test lzma_check_is_supported(block->check). | // Caller can test lzma_check_is_supported(block->check). | |||
| next->coder->check_pos = 0; | next->coder->check_pos = 0; | |||
| lzma_check_init(&next->coder->check, block->check); | lzma_check_init(&next->coder->check, block->check); | |||
| next->coder->ignore_check = block->version >= 1 | ||||
| ? block->ignore_check : false; | ||||
| // Initialize the filter chain. | // Initialize the filter chain. | |||
| return lzma_raw_decoder_init(&next->coder->next, allocator, | return lzma_raw_decoder_init(&next->coder->next, allocator, | |||
| block->filters); | block->filters); | |||
| } | } | |||
| extern LZMA_API(lzma_ret) | extern LZMA_API(lzma_ret) | |||
| lzma_block_decoder(lzma_stream *strm, lzma_block *block) | lzma_block_decoder(lzma_stream *strm, lzma_block *block) | |||
| { | { | |||
| lzma_next_strm_init(lzma_block_decoder_init, strm, block); | lzma_next_strm_init(lzma_block_decoder_init, strm, block); | |||
| End of changes. 8 change blocks. | ||||
| 7 lines changed or deleted | 20 lines changed or added | |||
This html diff was produced by rfcdiff 1.41. The latest version is available from http://tools.ietf.org/tools/rfcdiff/ | ||||