diff options
Diffstat (limited to 'src/liblzma/common')
-rw-r--r-- | src/liblzma/common/block_decoder.c | 5 | ||||
-rw-r--r-- | src/liblzma/common/block_encoder.c | 7 | ||||
-rw-r--r-- | src/liblzma/common/common.c | 20 | ||||
-rw-r--r-- | src/liblzma/common/index_decoder.c | 13 | ||||
-rw-r--r-- | src/liblzma/common/index_encoder.c | 11 | ||||
-rw-r--r-- | src/liblzma/common/index_hash.c | 13 | ||||
-rw-r--r-- | src/liblzma/common/lzip_decoder.c | 6 |
7 files changed, 57 insertions, 18 deletions
diff --git a/src/liblzma/common/block_decoder.c b/src/liblzma/common/block_decoder.c index 4827e0f0..be647d48 100644 --- a/src/liblzma/common/block_decoder.c +++ b/src/liblzma/common/block_decoder.c @@ -123,7 +123,10 @@ block_decode(void *coder_ptr, const lzma_allocator *allocator, return LZMA_DATA_ERROR; } - if (!coder->ignore_check) + // Don't waste time updating the integrity check if it will be + // ignored. Also skip it if no new output was produced. This + // avoids null pointer + 0 (undefined behavior) when out == 0. + if (!coder->ignore_check && out_used > 0) lzma_check_update(&coder->check, coder->block->check, out + out_start, out_used); diff --git a/src/liblzma/common/block_encoder.c b/src/liblzma/common/block_encoder.c index 520ecc5a..4a136ef6 100644 --- a/src/liblzma/common/block_encoder.c +++ b/src/liblzma/common/block_encoder.c @@ -77,8 +77,11 @@ block_encode(void *coder_ptr, const lzma_allocator *allocator, // checked it at the beginning of this function. coder->uncompressed_size += in_used; - lzma_check_update(&coder->check, coder->block->check, - in + in_start, in_used); + // Call lzma_check_update() only if input was consumed. This + // avoids null pointer + 0 (undefined behavior) when in == 0. + if (in_used > 0) + lzma_check_update(&coder->check, coder->block->check, + in + in_start, in_used); if (ret != LZMA_STREAM_END || action == LZMA_SYNC_FLUSH) return ret; diff --git a/src/liblzma/common/common.c b/src/liblzma/common/common.c index a708fdf1..baad3dd8 100644 --- a/src/liblzma/common/common.c +++ b/src/liblzma/common/common.c @@ -288,13 +288,21 @@ lzma_code(lzma_stream *strm, lzma_action action) strm->next_in, &in_pos, strm->avail_in, strm->next_out, &out_pos, strm->avail_out, action); - strm->next_in += in_pos; - strm->avail_in -= in_pos; - strm->total_in += in_pos; + // Updating next_in and next_out has to be skipped when they are NULL + // to avoid null pointer + 0 (undefined behavior). Do this by checking + // in_pos > 0 and out_pos > 0 because this way NULL + non-zero (a bug) + // will get caught one way or other. + if (in_pos > 0) { + strm->next_in += in_pos; + strm->avail_in -= in_pos; + strm->total_in += in_pos; + } - strm->next_out += out_pos; - strm->avail_out -= out_pos; - strm->total_out += out_pos; + if (out_pos > 0) { + strm->next_out += out_pos; + strm->avail_out -= out_pos; + strm->total_out += out_pos; + } strm->internal->avail_in = strm->avail_in; diff --git a/src/liblzma/common/index_decoder.c b/src/liblzma/common/index_decoder.c index 8622b2f0..19a31b3e 100644 --- a/src/liblzma/common/index_decoder.c +++ b/src/liblzma/common/index_decoder.c @@ -203,9 +203,16 @@ index_decode(void *coder_ptr, const lzma_allocator *allocator, } out: - // Update the CRC32, - coder->crc32 = lzma_crc32(in + in_start, - *in_pos - in_start, coder->crc32); + // Update the CRC32. + // + // Avoid null pointer + 0 (undefined behavior) in "in + in_start". + // In such a case we had no input and thus in_used == 0. + { + const size_t in_used = *in_pos - in_start; + if (in_used > 0) + coder->crc32 = lzma_crc32(in + in_start, + in_used, coder->crc32); + } return ret; } diff --git a/src/liblzma/common/index_encoder.c b/src/liblzma/common/index_encoder.c index c7cafb72..204490cc 100644 --- a/src/liblzma/common/index_encoder.c +++ b/src/liblzma/common/index_encoder.c @@ -153,8 +153,15 @@ index_encode(void *coder_ptr, out: // Update the CRC32. - coder->crc32 = lzma_crc32(out + out_start, - *out_pos - out_start, coder->crc32); + // + // Avoid null pointer + 0 (undefined behavior) in "out + out_start". + // In such a case we had no input and thus out_used == 0. + { + const size_t out_used = *out_pos - out_start; + if (out_used > 0) + coder->crc32 = lzma_crc32(out + out_start, + out_used, coder->crc32); + } return ret; } diff --git a/src/liblzma/common/index_hash.c b/src/liblzma/common/index_hash.c index f55f7bc8..52c3d650 100644 --- a/src/liblzma/common/index_hash.c +++ b/src/liblzma/common/index_hash.c @@ -328,9 +328,16 @@ lzma_index_hash_decode(lzma_index_hash *index_hash, const uint8_t *in, } out: - // Update the CRC32, - index_hash->crc32 = lzma_crc32(in + in_start, - *in_pos - in_start, index_hash->crc32); + // Update the CRC32. + // + // Avoid null pointer + 0 (undefined behavior) in "in + in_start". + // In such a case we had no input and thus in_used == 0. + { + const size_t in_used = *in_pos - in_start; + if (in_used > 0) + index_hash->crc32 = lzma_crc32(in + in_start, + in_used, index_hash->crc32); + } return ret; } diff --git a/src/liblzma/common/lzip_decoder.c b/src/liblzma/common/lzip_decoder.c index 20794f94..58c08674 100644 --- a/src/liblzma/common/lzip_decoder.c +++ b/src/liblzma/common/lzip_decoder.c @@ -262,7 +262,11 @@ lzip_decode(void *coder_ptr, const lzma_allocator *allocator, coder->member_size += *in_pos - in_start; coder->uncompressed_size += out_used; - if (!coder->ignore_check) + // Don't update the CRC32 if the integrity check will be + // ignored or if there was no new output. The latter is + // important in case out == NULL to avoid null pointer + 0 + // which is undefined behavior. + if (!coder->ignore_check && out_used > 0) coder->crc32 = lzma_crc32(out + out_start, out_used, coder->crc32); |