diff --git a/source/utils/extract.cpp b/source/utils/extract.cpp index 58a496d..38af44c 100644 --- a/source/utils/extract.cpp +++ b/source/utils/extract.cpp @@ -70,7 +70,11 @@ Result extractArchive(const std::string &archivePath, const std::string &wantedF a = archive_read_new(); archive_read_support_format_all(a); - if (archive_read_open_filename(a, archivePath.c_str(), 0x4000) != ARCHIVE_OK) return EXTRACT_ERROR_OPENFILE; + if (archive_read_open_filename(a, archivePath.c_str(), 0x4000) != ARCHIVE_OK) { + archive_read_close(a); + archive_read_free(a); + return EXTRACT_ERROR_OPENFILE; + } while(archive_read_next_header(a, &entry) == ARCHIVE_OK) { if (archive_entry_size(entry) > 0) { /* Ignore folders. */ @@ -92,14 +96,31 @@ Result extractArchive(const std::string &archivePath, const std::string &wantedF uint sizeLeft = archive_entry_size(entry); FILE *file = fopen(extractingFile.c_str(), "wb"); - if (!file) return EXTRACT_ERROR_WRITEFILE; + if (!file) { + archive_read_close(a); + archive_read_free(a); + return EXTRACT_ERROR_WRITEFILE; + } u8 *buf = new u8[0x30000]; - if (!buf) return EXTRACT_ERROR_ALLOC; + if (!buf) { + fclose(file); + archive_read_close(a); + archive_read_free(a); + return EXTRACT_ERROR_ALLOC; + } while(sizeLeft > 0) { u64 toRead = std::min(0x30000u, sizeLeft); ssize_t size = archive_read_data(a, buf, toRead); + // Archive error, stop extracting + if(size < 0) { + fclose(file); + delete[] buf; + archive_read_close(a); + archive_read_free(a); + return EXTRACT_ERROR_ARCHIVE; + } fwrite(buf, 1, size, file); sizeLeft -= size; writeOffset += size;