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/ |