size_t *size, int64_t *offset)
{
struct rar *rar = (struct rar *)(a->format->data);
+ int ret;
if (rar->bytes_unconsumed > 0) {
/* Consume as much as the decompressor actually used. */
switch (rar->compression_method)
{
case COMPRESS_METHOD_STORE:
- return read_data_stored(a, buff, size, offset);
+ ret = read_data_stored(a, buff, size, offset);
+ break;
case COMPRESS_METHOD_FASTEST:
case COMPRESS_METHOD_FAST:
case COMPRESS_METHOD_NORMAL:
case COMPRESS_METHOD_GOOD:
case COMPRESS_METHOD_BEST:
- return read_data_compressed(a, buff, size, offset);
+ ret = read_data_compressed(a, buff, size, offset);
+ if (ret != ARCHIVE_OK && ret != ARCHIVE_WARN)
+ __archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context, &g_szalloc);
+ break;
default:
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
"Unsupported compression method for RAR file.");
+ ret = ARCHIVE_FATAL;
+ break;
}
- return (ARCHIVE_FATAL);
+ return (ret);
}
static int
int ret = (ARCHIVE_OK), sym, code, lzss_offset, length, i;
rar = (struct rar *)(a->format->data);
- if (!rar->valid)
- return (ARCHIVE_FAILED);
do {
+ if (!rar->valid)
+ return (ARCHIVE_FAILED);
if (rar->ppmd_eod ||
(rar->dictionary_size && rar->offset >= rar->unp_size))
{
*buff = NULL;
*size = 0;
*offset = rar->offset;
- __archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context, &g_szalloc);
if (rar->file_crc != rar->crc_calculated) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"File CRC error");
else
bs = rar->bytes_uncopied;
ret = copy_from_lzss_window(a, buff, rar->offset, bs);
- if (ret != ARCHIVE_OK) {
- __archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context, &g_szalloc);
+ if (ret != ARCHIVE_OK)
return (ret);
- }
rar->offset += bs;
rar->bytes_uncopied -= bs;
if (*buff != NULL) {
}
if (!rar->br.next_in &&
- (ret = rar_br_preparation(a, &(rar->br))) < ARCHIVE_WARN) {
- __archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context, &g_szalloc);
+ (ret = rar_br_preparation(a, &(rar->br))) < ARCHIVE_WARN)
return (ret);
- }
- if (rar->start_new_table && ((ret = parse_codes(a)) < (ARCHIVE_WARN))) {
- __archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context, &g_szalloc);
+ if (rar->start_new_table && ((ret = parse_codes(a)) < (ARCHIVE_WARN)))
return (ret);
- }
if (rar->is_ppmd_block)
{
if ((sym = __archive_ppmd7_functions.Ppmd7_DecodeSymbol(
&rar->ppmd7_context, &rar->range_dec.p)) < 0)
{
- __archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context, &g_szalloc);
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
"Invalid symbol");
return (ARCHIVE_FATAL);
if ((code = __archive_ppmd7_functions.Ppmd7_DecodeSymbol(
&rar->ppmd7_context, &rar->range_dec.p)) < 0)
{
- __archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context, &g_szalloc);
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
"Invalid symbol");
return (ARCHIVE_FATAL);
continue;
case 3:
- __archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context,
- &g_szalloc);
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
"Parsing filters is unsupported.");
return (ARCHIVE_FAILED);
if ((code = __archive_ppmd7_functions.Ppmd7_DecodeSymbol(
&rar->ppmd7_context, &rar->range_dec.p)) < 0)
{
- __archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context,
- &g_szalloc);
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
"Invalid symbol");
return (ARCHIVE_FATAL);
if ((length = __archive_ppmd7_functions.Ppmd7_DecodeSymbol(
&rar->ppmd7_context, &rar->range_dec.p)) < 0)
{
- __archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context,
- &g_szalloc);
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
"Invalid symbol");
return (ARCHIVE_FATAL);
if ((length = __archive_ppmd7_functions.Ppmd7_DecodeSymbol(
&rar->ppmd7_context, &rar->range_dec.p)) < 0)
{
- __archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context,
- &g_szalloc);
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
"Invalid symbol");
return (ARCHIVE_FATAL);
else
bs = rar->bytes_uncopied;
ret = copy_from_lzss_window(a, buff, rar->offset, bs);
- if (ret != ARCHIVE_OK) {
- __archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context,
- &g_szalloc);
+ if (ret != ARCHIVE_OK)
return (ret);
- }
rar->offset += bs;
rar->bytes_uncopied -= bs;
/*
return (ARCHIVE_FATAL);
}
+ /* Make sure ppmd7_contest is freed before Ppmd7_Construct
+ * because reading a broken file cause this abnormal sequence. */
+ __archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context, &g_szalloc);
+
rar->bytein.a = a;
rar->bytein.Read = &ppmd_read;
__archive_ppmd7_functions.PpmdRAR_RangeDec_CreateVTable(&rar->range_dec);