mirror of
https://git.tukaani.org/xz.git
synced 2026-10-31 03:14:56 +00:00
xz: Make it an error if the totals in xz --list exceed UINT64_MAX
If at least three files are passed to xz --list, the totals might exceed the range of uint64_t. Previously wrong totals were displayed in this case. Now an error is shown as soon as an overflow would occur, and the remaining files aren't processed. In most other cases an error doesn't prevent xz from processing the remaining files, but in this case it feels OK because (1) the error should be very rare, (2) it keeps the code slightly simpler, and (3) with xz --robot --list the caller will likely ignore the output anyway when xz exits with a non-zero status. Co-authored-by: Lasse Collin <lasse.collin@tukaani.org> Fixes: https://github.com/tukaani-project/xz/pull/240
This commit is contained in:
parent
29f9ca3dbc
commit
102ea0ed12
@ -1142,12 +1142,36 @@ print_info_robot(xz_file_info *xfi, file_pair *pair)
|
||||
static void
|
||||
update_totals(const xz_file_info *xfi)
|
||||
{
|
||||
// TODO: Integer overflow checks
|
||||
const uint64_t streams = lzma_index_stream_count(xfi->idx);
|
||||
const uint64_t blocks = lzma_index_block_count(xfi->idx);
|
||||
const uint64_t compressed_size = lzma_index_file_size(xfi->idx);
|
||||
const uint64_t uncompressed_size
|
||||
= lzma_index_uncompressed_size(xfi->idx);
|
||||
|
||||
// Of these, totals.uncompressed_size is the most likely to overflow
|
||||
// because it doesn't require a huge file. Even that is likely to
|
||||
// happen only with invalid/crafted files.
|
||||
//
|
||||
// For simplicity, the error message refers to file sizes even though
|
||||
// we are checking other things too.
|
||||
if (totals.files == UINT64_MAX
|
||||
|| UINT64_MAX - totals.streams < streams
|
||||
|| UINT64_MAX - totals.blocks < blocks
|
||||
|| UINT64_MAX - totals.compressed_size
|
||||
< compressed_size
|
||||
|| UINT64_MAX - totals.uncompressed_size
|
||||
< uncompressed_size
|
||||
|| UINT64_MAX - totals.stream_padding
|
||||
< xfi->stream_padding) {
|
||||
message_fatal(_("Error: The total compressed or uncompressed "
|
||||
"size of the files is too large"));
|
||||
}
|
||||
|
||||
++totals.files;
|
||||
totals.streams += lzma_index_stream_count(xfi->idx);
|
||||
totals.blocks += lzma_index_block_count(xfi->idx);
|
||||
totals.compressed_size += lzma_index_file_size(xfi->idx);
|
||||
totals.uncompressed_size += lzma_index_uncompressed_size(xfi->idx);
|
||||
totals.streams += streams;
|
||||
totals.blocks += blocks;
|
||||
totals.compressed_size += compressed_size;
|
||||
totals.uncompressed_size += uncompressed_size;
|
||||
totals.stream_padding += xfi->stream_padding;
|
||||
totals.checks |= lzma_index_checks(xfi->idx);
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user