static bool rar_uncompress(ar_archive *ar, void *buffer, size_t count) { ar_archive_rar *rar = (ar_archive_rar *)ar; if (rar->entry.method == METHOD_STORE) { if (!rar_copy_stored(rar, buffer, count)) return false; } else if (rar->entry.method == METHOD_FASTEST || rar->entry.method == METHOD_FAST || rar->entry.method == METHOD_NORMAL || rar->entry.method == METHOD_GOOD || rar->entry.method == METHOD_BEST) { if (rar->entry.restart_solid && !rar_restart_solid(rar)) { warn("Failed to produce the required solid decompression state"); return false; } if (!rar_uncompress_part(rar, buffer, count)) return false; } else { warn("Unknown compression method %02x", rar->entry.method); return false; } rar->progr.crc = ar_crc32(rar->progr.crc, buffer, count); if (rar->progr.bytes_done < rar->super.entry_size_uncompressed) return true; if (rar->progr.data_left) log("Compressed block has more data than required"); if (rar->progr.crc != rar->entry.crc) { warn("Checksum of extracted data doesn't match"); return false; } return true; }
static bool rar_uncompress(ar_archive *ar, void *buffer, size_t count) { ar_archive_rar *rar = (ar_archive_rar *)ar; if (count > ar->entry_size_uncompressed - rar->progress.bytes_done) { warn("Requesting too much data (%" PRIuPTR " < %" PRIuPTR ")", ar->entry_size_uncompressed - rar->progress.bytes_done, count); return false; } if (rar->entry.method == METHOD_STORE) { if (!rar_copy_stored(rar, buffer, count)) return false; } else if (rar->entry.method == METHOD_FASTEST || rar->entry.method == METHOD_FAST || rar->entry.method == METHOD_NORMAL || rar->entry.method == METHOD_GOOD || rar->entry.method == METHOD_BEST) { if (rar->solid.restart && !rar_restart_solid(ar)) { warn("Failed to produce the required solid decompression state"); return false; } if (!rar_uncompress_part(rar, buffer, count)) return false; } else { warn("Unknown compression method %#02x", rar->entry.method); return false; } rar->progress.crc = ar_crc32(rar->progress.crc, buffer, count); if (rar->progress.bytes_done < ar->entry_size_uncompressed) return true; if (rar->progress.data_left) log("Compressed block has more data than required"); rar->solid.part_done = true; rar->solid.size_total += rar->progress.bytes_done; if (rar->progress.crc != rar->entry.crc) { warn("Checksum of extracted data doesn't match"); return false; } return true; }