From ce5d6b6b922c394724ef21e053e1547824642ce1 Mon Sep 17 00:00:00 2001 From: Duncan Horn <40036384+dunhor@users.noreply.github.com> Date: Mon, 22 Apr 2024 23:25:39 -0700 Subject: [PATCH] rar: Avoid overwriting data at "end" of circular window buffer (#2124) fix "File CRC Error" when extracting specific rar4 archives Fixes #1794 --- libarchive/archive_read_support_format_rar.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/libarchive/archive_read_support_format_rar.c b/libarchive/archive_read_support_format_rar.c index 266d0ee99..79669a8f4 100644 --- a/libarchive/archive_read_support_format_rar.c +++ b/libarchive/archive_read_support_format_rar.c @@ -2176,6 +2176,19 @@ read_data_compressed(struct archive_read *a, const void **buff, size_t *size, { start = rar->offset; end = start + rar->dictionary_size; + + /* We don't want to overflow the window and overwrite data that we write + * at 'start'. Therefore, reduce the end length by the maximum match size, + * which is 260 bytes. You can compute this maximum by looking at the + * definition of 'expand', in particular when 'symbol >= 271'. */ + /* NOTE: It's possible for 'dictionary_size' to be less than this 260 + * value, however that will only be the case when 'unp_size' is small, + * which should only happen when the entry size is small and there's no + * risk of overflowing the buffer */ + if (rar->dictionary_size > 260) { + end -= 260; + } + if (rar->filters.filterstart < end) { end = rar->filters.filterstart; }