/* The data for table generation is compressed using a simple RLE-like
* algorithm when storing zeroes, so we need to unpack it first. */
for(w = 0, i = 0; w < HUFF_BC;) {
+ if(i >= rar->cstate.cur_block_size) {
+ /* Truncated data, can't continue. */
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Truncated data in huffman tables");
+ return ARCHIVE_FATAL;
+ }
+
value = (p[i] & nibble_mask) >> nibble_shift;
if(nibble_mask == 0x0F)
for(i = 0; i < HUFF_TABLE_SIZE;) {
uint16_t num;
+ if((rar->bits.in_addr + 6) >= rar->cstate.cur_block_size) {
+ /* Truncated data, can't continue. */
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Truncated data in huffman tables (#2)");
+ return ARCHIVE_FATAL;
+ }
+
ret = decode_number(a, &rar->cstate.bd, p, &num);
if(ret != ARCHIVE_OK) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
EPILOGUE();
}
+
+DEFINE_TEST(test_read_format_rar5_truncated_huff)
+{
+ uint8_t buf[16];
+
+ PROLOGUE("test_read_format_rar5_truncated_huff.rar");
+
+ assertA(0 == archive_read_next_header(a, &ae));
+ /* This archive is invalid. However, processing it shouldn't cause any
+ * errors related to undefined operations when using -fsanitize. */
+ assertA(ARCHIVE_FATAL == archive_read_data(a, buf, sizeof(buf)));
+ assertA(ARCHIVE_FATAL == archive_read_next_header(a, &ae));
+
+ EPILOGUE();
+}
--- /dev/null
+begin 644 test_read_format_rar5_truncated_huff.rar
+M4F%R(1H'`0"-[P+2``'#]#P\7P$'`0"-[P+2``+2`!;#M#Q::7!)2?__'`!I
+M?_O_0B\*0RX-,'%O.\(#!-'^T#4````0`P1_``!#(3`P,./H`P```*^OKZ^O
+MKZ^OKZ^OKZ^OKZ^OKZ^OKZ^OKZ^OKZ^OKZ^OKZ\0`*^OKZ^A``KZ``$`2^\#
+9T>WMNP$+-5H*^@`!`$OOB]$````0"S5:*@``
+`
+end