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/