From: Duncan Horn <40036384+dunhor@users.noreply.github.com> Date: Mon, 1 Apr 2024 18:13:19 +0000 (-0700) Subject: rar5: don't continue if the last block produced no data (#2105) X-Git-Tag: v3.7.3~5 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=77b783226d03f5ffd13790f94489828d10964f82;p=thirdparty%2Flibarchive.git rar5: don't continue if the last block produced no data (#2105) There appear to be RAR5 archives out in the wild that have blocks at the end of files that don't produce any data. The code in libarchive has an infinite loop that won't break until it processes a block that produces data, which will end up reading past the end of the file if the last block in the file produces no data. --- diff --git a/libarchive/archive_read_support_format_rar5.c b/libarchive/archive_read_support_format_rar5.c index 1f9099439..e8846a5b0 100644 --- a/libarchive/archive_read_support_format_rar5.c +++ b/libarchive/archive_read_support_format_rar5.c @@ -495,6 +495,11 @@ uint8_t bf_is_table_present(const struct compressed_block_header* hdr) { return (hdr->block_flags_u8 >> 7) & 1; } +static inline +uint8_t bf_is_last_block(const struct compressed_block_header* hdr) { + return (hdr->block_flags_u8 >> 6) & 1; +} + static inline struct rar5* get_context(struct archive_read* a) { return (struct rar5*) a->format->data; } @@ -3757,7 +3762,12 @@ static int do_uncompress_file(struct archive_read* a) { if(rar->cstate.last_write_ptr == rar->cstate.write_ptr) { /* The block didn't generate any new data, - * so just process a new block. */ + * so just process a new block if this one + * wasn't the last block in the file. */ + if (bf_is_last_block(&rar->last_block_hdr)) { + return ARCHIVE_EOF; + } + continue; }