libarchive/test/test_read_format_rar_encryption_header.c \
libarchive/test/test_read_format_rar_filter.c \
libarchive/test/test_read_format_rar_invalid1.c \
+ libarchive/test/test_read_format_rar_overflow.c \
libarchive/test/test_read_format_rar5.c \
libarchive/test/test_read_format_raw.c \
libarchive/test/test_read_format_tar.c \
libarchive/test/test_read_format_rar_multivolume.part0004.rar.uu \
libarchive/test/test_read_format_rar_newsub_huge.rar.uu \
libarchive/test/test_read_format_rar_noeof.rar.uu \
+ libarchive/test/test_read_format_rar_overflow.rar.uu \
libarchive/test/test_read_format_rar_ppmd_lzss_conversion.rar.uu \
libarchive/test/test_read_format_rar_ppmd_use_after_free.rar.uu \
libarchive/test/test_read_format_rar_ppmd_use_after_free2.rar.uu \
static int rar_decode_byte(struct archive_read*, uint8_t *);
static int execute_filter(struct archive_read*, struct rar_filter *,
struct rar_virtual_machine *, size_t);
-static int copy_from_lzss_window(struct archive_read *, void *, int64_t, int);
+static int copy_from_lzss_window(struct archive_read *, uint8_t *, int64_t, int);
static inline void vm_write_32(struct rar_virtual_machine*, size_t, uint32_t);
static inline uint32_t vm_read_32(struct rar_virtual_machine*, size_t);
}
if ((symbol = read_next_symbol(a, &rar->maincode)) < 0)
- return (ARCHIVE_FATAL);
+ goto bad_data;
if (symbol < 256)
{
else
{
if (parse_codes(a) != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
+ goto bad_data;
continue;
}
}
else if(symbol==257)
{
if (!read_filter(a, end))
- return (ARCHIVE_FATAL);
+ goto bad_data;
continue;
}
else if(symbol==258)
{
if ((lowoffsetsymbol =
read_next_symbol(a, &rar->lowoffsetcode)) < 0)
- return (ARCHIVE_FATAL);
+ goto bad_data;
if(lowoffsetsymbol == 16)
{
rar->numlowoffsetrepeats = 15;
}
static int
-copy_from_lzss_window(struct archive_read *a, void *buffer,
+copy_from_lzss_window(struct archive_read *a, uint8_t *buffer,
int64_t startpos, int length)
{
int windowoffs, firstpart;
}
if (firstpart < length) {
memcpy(buffer, &rar->lzss.window[windowoffs], firstpart);
- memcpy(buffer, &rar->lzss.window[0], length - firstpart);
+ memcpy(buffer + firstpart, &rar->lzss.window[0], length - firstpart);
} else {
memcpy(buffer, &rar->lzss.window[windowoffs], length);
}
else
blocklength = prog ? prog->oldfilterlength : 0;
+ if (blocklength > rar->dictionary_size)
+ return 0;
+
registers[3] = PROGRAM_SYSTEM_GLOBAL_ADDRESS;
registers[4] = blocklength;
registers[5] = prog ? prog->usagecount : 0;
test_read_format_rar_encryption_partially.c
test_read_format_rar_invalid1.c
test_read_format_rar_filter.c
+ test_read_format_rar_overflow.c
test_read_format_rar5.c
test_read_format_raw.c
test_read_format_tar.c
--- /dev/null
+/*-
+ * Copyright (c) 2003-2025 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "test.h"
+
+DEFINE_TEST(test_read_format_rar_overflow)
+{
+ struct archive *a;
+ struct archive_entry *ae;
+ const char reffile[] = "test_read_format_rar_overflow.rar";
+ const void *buff;
+ size_t size;
+ int64_t offset;
+
+ extract_reference_file(reffile);
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, reffile, 1024));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt(48, archive_entry_size(ae));
+ /* The next call should reproduce Issue #2565 */
+ assertEqualIntA(a, ARCHIVE_FATAL, archive_read_data_block(a, &buff, &size, &offset));
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
--- /dev/null
+begin 644 test_read_format_rar_overflow.rar
+M4F%R(1H'`,($=```(0`@`0``,`````(````````````S`0``````,`"_B%_:
+MZ?^[:7``?S!!,`@P,KB@,T@RN33)MTEB@5Z3<`DP`K35`.0P63@P<,Q&0?#,
+MA##,,",S,(@P,#,@##`&,#":(3`!,#"(`9HPS,,S13`P,#`P,*`PHPS,,S1A
+M,!,!,#","9H@S12D#$PP!C`P`*'F03":,,T8H`@\,/DPJS!/,"30,#`3N%LP
+MCQ6:S3"!,#LP22<-,$5%B"5B$S!)(&*>G#+@!`E`%0ODC])62=DO,)BYJX'P
+M=/LPZ3!!008?%S`P,#`P,#`P,#`P,#`P,#`P,#`P2$PP,#`P03!(,#`P,#`&
+M,`7),#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P
+-,#`P,#`P,#`P,#`P,```
+`
+end