Fixed bzip2 not returning read = 0 on next call after end of stream.

Fixed lzma trying to decode uncompressed size which isn't used in zip format.
This commit is contained in:
Nathan Moinvaziri 2017-10-18 11:35:53 -07:00
parent 8f67ff9b16
commit 489eea4e6d
4 changed files with 59 additions and 72 deletions

View file

@ -71,57 +71,38 @@ alone_decode(lzma_coder *coder,
case SEQ_DICTIONARY_SIZE:
coder->options.dict_size
|= (size_t)(in[*in_pos]) << (coder->pos * 8);
++*in_pos;
if (++coder->pos < 4)
break;
if (++coder->pos == 4) {
if (coder->picky && coder->options.dict_size
!= UINT32_MAX) {
// A hack to ditch tons of false positives:
// We allow only dictionary sizes that are
// 2^n or 2^n + 2^(n-1). LZMA_Alone created
// only files with 2^n, but accepts any
// dictionary size.
uint32_t d = coder->options.dict_size - 1;
d |= d >> 2;
d |= d >> 3;
d |= d >> 4;
d |= d >> 8;
d |= d >> 16;
++d;
if (coder->picky && coder->options.dict_size
!= UINT32_MAX) {
// A hack to ditch tons of false positives:
// We allow only dictionary sizes that are
// 2^n or 2^n + 2^(n-1). LZMA_Alone created
// only files with 2^n, but accepts any
// dictionary size.
uint32_t d = coder->options.dict_size - 1;
d |= d >> 2;
d |= d >> 3;
d |= d >> 4;
d |= d >> 8;
d |= d >> 16;
++d;
if (d != coder->options.dict_size)
return LZMA_FORMAT_ERROR;
}
coder->pos = 0;
coder->sequence = SEQ_UNCOMPRESSED_SIZE;
if (d != coder->options.dict_size)
return LZMA_FORMAT_ERROR;
}
++*in_pos;
break;
coder->uncompressed_size = LZMA_VLI_UNKNOWN;
case SEQ_UNCOMPRESSED_SIZE:
coder->uncompressed_size
|= (lzma_vli)(in[*in_pos]) << (coder->pos * 8);
++*in_pos;
if (++coder->pos < 8)
break;
// Calculate the memory usage so that it is ready
// for SEQ_CODER_INIT.
coder->memusage = lzma_lzma_decoder_memusage(&coder->options)
+ LZMA_MEMUSAGE_BASE;
// Another hack to ditch false positives: Assume that
// if the uncompressed size is known, it must be less
// than 256 GiB.
if (coder->picky
&& coder->uncompressed_size != LZMA_VLI_UNKNOWN
&& coder->uncompressed_size
>= (LZMA_VLI_C(1) << 38))
return LZMA_FORMAT_ERROR;
// Calculate the memory usage so that it is ready
// for SEQ_CODER_INIT.
coder->memusage = lzma_lzma_decoder_memusage(&coder->options)
+ LZMA_MEMUSAGE_BASE;
coder->pos = 0;
coder->sequence = SEQ_CODER_INIT;
coder->pos = 0;
coder->sequence = SEQ_CODER_INIT;
// Fall through

View file

@ -118,9 +118,6 @@ alone_encoder_init(lzma_next_coder *next, const lzma_allocator *allocator,
unaligned_write32le(next->coder->header + 1, d);
// - Uncompressed size (always unknown and using EOPM)
//memset(next->coder->header + 1 + 4, 0xFF, 8);
// Initialize the LZMA encoder.
const lzma_filter_info filters[2] = {
{

View file

@ -45,6 +45,7 @@ typedef struct mz_stream_bzip_s {
bz_stream bzstream;
uint8_t buffer[INT16_MAX];
int32_t buffer_len;
int16_t stream_end;
int64_t total_in;
int64_t total_out;
int64_t max_total_in;
@ -91,6 +92,7 @@ int32_t mz_stream_bzip_open(void *stream, const char *path, int32_t mode)
return MZ_STREAM_ERROR;
bzip->initialized = 1;
bzip->stream_end = 0;
bzip->mode = mode;
return MZ_OK;
}
@ -118,6 +120,10 @@ int32_t mz_stream_bzip_read(void *stream, void *buf, int32_t size)
int32_t read = 0;
int16_t err = BZ_OK;
if (bzip->stream_end)
return 0;
bzip->bzstream.next_out = (char *)buf;
bzip->bzstream.avail_out = (uint16_t)size;
@ -155,14 +161,14 @@ int32_t mz_stream_bzip_read(void *stream, void *buf, int32_t size)
total_out_after = bzip->bzstream.total_out_lo32 +
(((uint64_t)bzip->bzstream.total_out_hi32) << 32);
in_bytes = (uint32_t)(total_in_before - total_in_after);
out_bytes = (uint32_t)(total_out_after - total_out_before);
total_in += in_bytes;
total_out += out_bytes;
total_in += (uint32_t)(total_in_before - total_in_after);
total_out += (uint32_t)(total_out_after - total_out_before);
if (err == BZ_STREAM_END)
{
bzip->stream_end = 1;
break;
}
if (err != BZ_RUN_OK)
{
bzip->error = err;
@ -299,6 +305,9 @@ int32_t mz_stream_bzip_get_prop_int64(void *stream, int32_t prop, int64_t *value
case MZ_STREAM_PROP_TOTAL_OUT:
*value = bzip->total_out;
return MZ_OK;
case MZ_STREAM_PROP_HEADER_SIZE:
*value = 0;
return MZ_OK;
}
return MZ_EXIST_ERROR;
}

View file

@ -24,13 +24,7 @@
/***************************************************************************/
#ifndef DEF_MEM_LEVEL
# if MAX_MEM_LEVEL >= 8
# define DEF_MEM_LEVEL 8
# else
# define DEF_MEM_LEVEL MAX_MEM_LEVEL
# endif
#endif
#define MZ_LZMA_HEADER_SIZE (4)
/***************************************************************************/
@ -76,6 +70,8 @@ int32_t mz_stream_lzma_open(void *stream, const char *path, int32_t mode)
lzma_filter filters[LZMA_FILTERS_MAX + 1];
lzma_options_lzma opt_lzma = { 0 };
uint32_t size = 0;
uint8_t major = 0;
uint8_t minor = 0;
lzma->lstream.total_in = 0;
lzma->lstream.total_out = 0;
@ -103,7 +99,7 @@ int32_t mz_stream_lzma_open(void *stream, const char *path, int32_t mode)
mz_stream_write_uint8(lzma->stream.base, LZMA_VERSION_MINOR);
mz_stream_write_uint16(lzma->stream.base, size);
lzma->total_out += 4;
lzma->total_out += MZ_LZMA_HEADER_SIZE;
lzma->error = lzma_alone_encoder(&lzma->lstream, &opt_lzma);
}
@ -112,7 +108,13 @@ int32_t mz_stream_lzma_open(void *stream, const char *path, int32_t mode)
lzma->lstream.next_in = lzma->buffer;
lzma->lstream.avail_in = 0;
lzma->error = lzma_stream_decoder(&lzma->lstream, UINT64_MAX, LZMA_CONCATENATED);
mz_stream_read_uint8(lzma->stream.base, &major);
mz_stream_read_uint8(lzma->stream.base, &minor);
mz_stream_read_uint16(lzma->stream.base, &size);
lzma->total_in += MZ_LZMA_HEADER_SIZE;
lzma->error = lzma_alone_decoder(&lzma->lstream, UINT64_MAX, LZMA_CONCATENATED);
}
if (lzma->error != LZMA_OK)
@ -138,8 +140,6 @@ int32_t mz_stream_lzma_read(void *stream, void *buf, int32_t size)
uint64_t total_out_before = 0;
uint64_t total_in_after = 0;
uint64_t total_out_after = 0;
uint32_t in_bytes = 0;
uint32_t out_bytes = 0;
uint32_t total_in = 0;
uint32_t total_out = 0;
int32_t bytes_to_read = 0;
@ -180,14 +180,11 @@ int32_t mz_stream_lzma_read(void *stream, void *buf, int32_t size)
err = lzma_code(&lzma->lstream, LZMA_RUN);
total_in_before = lzma->lstream.avail_in;
total_in_after = lzma->lstream.avail_in;
total_out_after = lzma->lstream.total_out;
in_bytes = (uint32_t)(total_in_before - total_in_after);
out_bytes = (uint32_t)(total_out_after - total_out_before);
total_in += in_bytes;
total_out += out_bytes;
total_in += (uint32_t)(total_in_before - total_in_after);
total_out += (uint32_t)(total_out_after - total_out_before);
if (err == LZMA_STREAM_END)
break;
@ -323,6 +320,9 @@ int32_t mz_stream_lzma_get_prop_int64(void *stream, int32_t prop, int64_t *value
case MZ_STREAM_PROP_TOTAL_OUT:
*value = lzma->total_out;
return MZ_OK;
case MZ_STREAM_PROP_HEADER_SIZE:
*value = MZ_LZMA_HEADER_SIZE;
return MZ_OK;
}
return MZ_EXIST_ERROR;
}
@ -339,7 +339,7 @@ int32_t mz_stream_lzma_set_prop_int64(void *stream, int32_t prop, int64_t value)
lzma->preset = LZMA_PRESET_DEFAULT;
return MZ_OK;
case MZ_STREAM_PROP_TOTAL_IN_MAX:
lzma->max_total_in = value;
lzma->max_total_in = value + MZ_LZMA_HEADER_SIZE;
return MZ_OK;
}
return MZ_EXIST_ERROR;