diff options
-rw-r--r-- | Userland/Utilities/CMakeLists.txt | 2 | ||||
-rw-r--r-- | Userland/Utilities/unzip.cpp | 11 |
2 files changed, 11 insertions, 2 deletions
diff --git a/Userland/Utilities/CMakeLists.txt b/Userland/Utilities/CMakeLists.txt index 601885305b..c4582aea8d 100644 --- a/Userland/Utilities/CMakeLists.txt +++ b/Userland/Utilities/CMakeLists.txt @@ -121,7 +121,7 @@ target_link_libraries(test-fuzz PRIVATE LibGemini LibGfx LibHTTP LibIPC LibJS Li target_link_libraries(test-imap PRIVATE LibIMAP) target_link_libraries(test-pthread PRIVATE LibThreading) target_link_libraries(unveil PRIVATE LibMain) -target_link_libraries(unzip PRIVATE LibArchive LibCompress) +target_link_libraries(unzip PRIVATE LibArchive LibCompress LibCrypto) target_link_libraries(update-cpp-test-results PRIVATE LibCpp) target_link_libraries(useradd PRIVATE LibCrypt) target_link_libraries(wallpaper PRIVATE LibGfx LibGUI) diff --git a/Userland/Utilities/unzip.cpp b/Userland/Utilities/unzip.cpp index ebf1171131..39c7b1e07c 100644 --- a/Userland/Utilities/unzip.cpp +++ b/Userland/Utilities/unzip.cpp @@ -14,6 +14,7 @@ #include <LibCore/File.h> #include <LibCore/MappedFile.h> #include <LibCore/System.h> +#include <LibCrypto/Checksum/CRC32.h> #include <sys/stat.h> static bool unpack_zip_member(Archive::ZipMember zip_member, bool quiet) @@ -37,13 +38,14 @@ static bool unpack_zip_member(Archive::ZipMember zip_member, bool quiet) if (!quiet) outln(" extracting: {}", zip_member.name); - // TODO: verify CRC32s match! + Crypto::Checksum::CRC32 checksum; switch (zip_member.compression_method) { case Archive::ZipCompressionMethod::Store: { if (!new_file->write(zip_member.compressed_data.data(), zip_member.compressed_data.size())) { warnln("Can't write file contents in {}: {}", zip_member.name, new_file->error_string()); return false; } + checksum.update({ zip_member.compressed_data.data(), zip_member.compressed_data.size() }); break; } case Archive::ZipCompressionMethod::Deflate: { @@ -60,6 +62,7 @@ static bool unpack_zip_member(Archive::ZipMember zip_member, bool quiet) warnln("Can't write file contents in {}: {}", zip_member.name, new_file->error_string()); return false; } + checksum.update({ decompressed_data.value().data(), decompressed_data.value().size() }); break; } default: @@ -71,6 +74,12 @@ static bool unpack_zip_member(Archive::ZipMember zip_member, bool quiet) return false; } + if (checksum.digest() != zip_member.crc32) { + warnln("Failed decompressing file {}: CRC32 mismatch", zip_member.name); + MUST(new_file->remove(zip_member.name, Core::File::RecursionMode::Disallowed, true)); + return false; + } + return true; } |