const unsigned char *next_in;
int64_t avail_in;
int64_t total_in;
+ int64_t stream_in;
unsigned char *next_out;
int64_t avail_out;
int64_t total_out;
struct _7zip *zip = (struct _7zip *)(a->format->data);
Byte b;
- if (zip->ppstream.avail_in == 0) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Truncated RAR file data");
- zip->ppstream.overconsumed = 1;
- return (0);
+ if (zip->ppstream.avail_in <= 0) {
+ // Ppmd7_DecodeSymbol might require reading multiple bytes and we are on boundary; last resort to read using __archive_read_ahead.
+ ssize_t bytes_avail = 0;
+ const uint8_t* data = __archive_read_ahead(a, zip->ppstream.stream_in+1, &bytes_avail);
+ if(bytes_avail < zip->ppstream.stream_in+1) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Truncated 7z file data");
+ zip->ppstream.overconsumed = 1;
+ return (0);
+ }
+ zip->ppstream.next_in++;
+ b = data[zip->ppstream.stream_in];
+ zip->ppstream.avail_in--;
+ zip->ppstream.total_in++;
+ zip->ppstream.stream_in++;
+ } else {
+ b = *zip->ppstream.next_in++;
+ zip->ppstream.avail_in--;
+ zip->ppstream.total_in++;
+ zip->ppstream.stream_in++;
}
- b = *zip->ppstream.next_in++;
- zip->ppstream.avail_in--;
- zip->ppstream.total_in++;
return (b);
}
}
zip->ppstream.next_in = t_next_in;
zip->ppstream.avail_in = t_avail_in;
+ zip->ppstream.stream_in = 0;
zip->ppstream.next_out = t_next_out;
zip->ppstream.avail_out = t_avail_out;
if (zip->ppmd7_stat == 0) {