From 0c146182123b767c6a435c132a4b1e09645b45c8 Mon Sep 17 00:00:00 2001 From: craftablescience Date: Sat, 20 Jul 2024 01:49:07 -0400 Subject: [PATCH 1/2] fix: normalize slashes of stored vpk paths --- src/create.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/create.cpp b/src/create.cpp index a3a28f6..a27f1be 100644 --- a/src/create.cpp +++ b/src/create.cpp @@ -70,7 +70,8 @@ auto createFromRoot( std::string_view root_, std::string_view indexLocation, boo } // relative path - const auto pathRel{ std::filesystem::relative( path, root ).string() }; + auto pathRel{ std::filesystem::relative( path, root ).string() }; + sourcepp::string::normalizeSlashes( pathRel ); auto breaker{ false }; for ( const auto& exclusion : exclusionREs ) { From e81bd26b75ad2863047557e4a8de4c2d00d4c225 Mon Sep 17 00:00:00 2001 From: craftablescience Date: Sat, 20 Jul 2024 02:34:52 -0400 Subject: [PATCH 2/2] fix: use SHA1 over SHA256 --- CMakeLists.txt | 2 +- src/create.cpp | 32 ++++++++++++++++---------------- src/verify.cpp | 44 ++++++++++++++++++++++---------------------- 3 files changed, 39 insertions(+), 39 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4cf84c8..a147079 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.24) project( verifier DESCRIPTION "A tool used to verify a game's install." - VERSION 0.3.0 + VERSION 0.3.1 ) set( CMAKE_CXX_STANDARD 20 ) set( CMAKE_CXX_STANDARD_REQUIRED ON ) diff --git a/src/create.cpp b/src/create.cpp index a27f1be..3e1f196 100644 --- a/src/create.cpp +++ b/src/create.cpp @@ -121,31 +121,31 @@ auto createFromRoot( std::string_view root_, std::string_view indexLocation, boo const auto size{ std::ftell( file ) }; std::fseek( file, 0, 0 ); - // sha256/crc32 - CryptoPP::SHA256 sha256er{}; + // sha1/crc32 + CryptoPP::SHA1 sha1er{}; CryptoPP::CRC32 crc32er{}; unsigned char buffer[2048]; while ( auto bufCount = std::fread( buffer, 1, sizeof( buffer ), file ) ) { - sha256er.Update( buffer, bufCount ); + sha1er.Update( buffer, bufCount ); crc32er.Update( buffer, bufCount ); } std::fclose( file ); - std::array sha256Hash{}; - sha256er.Final( sha256Hash.data() ); + std::array sha1Hash{}; + sha1er.Final( sha1Hash.data() ); std::array crc32Hash{}; crc32er.Final( crc32Hash.data() ); - std::string sha256HashStr; + std::string sha1HashStr; std::string crc32HashStr; { - CryptoPP::StringSource sha256HashStrSink{ sha256Hash.data(), sha256Hash.size(), true, new CryptoPP::HexEncoder{ new CryptoPP::StringSink{ sha256HashStr } } }; + CryptoPP::StringSource sha1HashStrSink{ sha1Hash.data(), sha1Hash.size(), true, new CryptoPP::HexEncoder{ new CryptoPP::StringSink{ sha1HashStr } } }; CryptoPP::StringSource crc32HashStrSink{ crc32Hash.data(), crc32Hash.size(), true, new CryptoPP::HexEncoder{ new CryptoPP::StringSink{ crc32HashStr } } }; } // write out entry - writer << fmt::format( ".\xFF{}\xFF{}\xFF{}\xFF{}\xFF\xFD", pathRel, size, sha256HashStr, crc32HashStr ); + writer << fmt::format( ".\xFF{}\xFF{}\xFF{}\xFF{}\xFF\xFD", pathRel, size, sha1HashStr, crc32HashStr ); Log_Info( "Processed file `{}`", path ); count += 1; } @@ -193,21 +193,21 @@ static auto enterVPK( std::ofstream& writer, std::string_view vpkPath, std::stri continue; } - // sha256 (crc32 is already computed) - CryptoPP::SHA256 sha256er{}; - sha256er.Update( reinterpret_cast( entryData->data() ), entryData->size() ); - std::array sha256Hash{}; - sha256er.Final( sha256Hash.data() ); + // sha1 (crc32 is already computed) + CryptoPP::SHA1 sha1er{}; + sha1er.Update( reinterpret_cast( entryData->data() ), entryData->size() ); + std::array sha1Hash{}; + sha1er.Final( sha1Hash.data() ); - std::string sha256HashStr; + std::string sha1HashStr; std::string crc32HashStr; { - CryptoPP::StringSource sha256HashStrSink{ sha256Hash.data(), sha256Hash.size(), true, new CryptoPP::HexEncoder{ new CryptoPP::StringSink{ sha256HashStr } } }; + CryptoPP::StringSource sha1HashStrSink{ sha1Hash.data(), sha1Hash.size(), true, new CryptoPP::HexEncoder{ new CryptoPP::StringSink{ sha1HashStr } } }; CryptoPP::StringSource crc32HashStrSink{ reinterpret_cast( &entry.crc32 ), sizeof( entry.crc32 ), true, new CryptoPP::HexEncoder{ new CryptoPP::StringSink{ crc32HashStr } } }; } // write out entry - writer << fmt::format( "{}\xFF{}\xFF{}\xFF{}\xFF{}\xFF\xFD", vpkPathRel, entry.path, entryData->size(), sha256HashStr, crc32HashStr ); + writer << fmt::format( "{}\xFF{}\xFF{}\xFF{}\xFF{}\xFF\xFD", vpkPathRel, entry.path, entryData->size(), sha1HashStr, crc32HashStr ); Log_Info( "Processed file `{}/{}`", vpkPath, entry.path ); } } diff --git a/src/verify.cpp b/src/verify.cpp index f5da57c..0329339 100644 --- a/src/verify.cpp +++ b/src/verify.cpp @@ -16,7 +16,7 @@ #include "log.hpp" -static auto verifyArchivedFile( const std::string& archivePath, const std::string& entryPath, std::uint64_t expectedSize, std::string_view expectedSha256, std::string_view expectedCrc32, unsigned int& entries, unsigned int& errors ) -> void; +static auto verifyArchivedFile( const std::string& archivePath, const std::string& entryPath, std::uint64_t expectedSize, std::string_view expectedSha1, std::string_view expectedCrc32, unsigned int& entries, unsigned int& errors ) -> void; static auto splitString( const std::string& string, const std::string& delim ) -> std::vector; @@ -59,7 +59,7 @@ auto verify( std::string_view root_, std::string_view indexLocation ) -> int { const auto& archive{ split[ 0 ] }; const auto& pathRel{ split[ 1 ] }; const auto expectedSize{ std::stoull( split[ 2 ] ) }; - const auto& expectedSha256{ split[ 3 ] }; + const auto& expectedSha1{ split[ 3 ] }; const auto& expectedCrc32{ split[ 4 ] }; // verify it @@ -73,7 +73,7 @@ auto verify( std::string_view root_, std::string_view indexLocation ) -> int { } if ( insideArchive ) { - verifyArchivedFile( path.string(), pathRel, expectedSize, expectedSha256, expectedCrc32, entries, errors ); + verifyArchivedFile( path.string(), pathRel, expectedSize, expectedSha1, expectedCrc32, entries, errors ); continue; } @@ -103,30 +103,30 @@ auto verify( std::string_view root_, std::string_view indexLocation ) -> int { } std::fseek( file, 0, 0 ); - // sha256/crc32 - CryptoPP::SHA256 sha256er{}; + // sha1/crc32 + CryptoPP::SHA1 sha1er{}; CryptoPP::CRC32 crc32er{}; unsigned char buffer[2048]; while ( auto count = std::fread( buffer, 1, sizeof( buffer ), file ) ) { - sha256er.Update( buffer, count ); + sha1er.Update( buffer, count ); crc32er.Update( buffer, count ); } - std::array sha256Hash{}; - sha256er.Final( sha256Hash.data() ); + std::array sha1Hash{}; + sha1er.Final( sha1Hash.data() ); std::array crc32Hash{}; crc32er.Final( crc32Hash.data() ); - std::string sha256HashStr; + std::string sha1HashStr; std::string crc32HashStr; { - CryptoPP::StringSource sha256HashStrSink{ sha256Hash.data(), sha256Hash.size(), true, new CryptoPP::HexEncoder{ new CryptoPP::StringSink{ sha256HashStr } } }; + CryptoPP::StringSource sha1HashStrSink{ sha1Hash.data(), sha1Hash.size(), true, new CryptoPP::HexEncoder{ new CryptoPP::StringSink{ sha1HashStr } } }; CryptoPP::StringSource crc32HashStrSink{ crc32Hash.data(), crc32Hash.size(), true, new CryptoPP::HexEncoder{ new CryptoPP::StringSink{ crc32HashStr } } }; } - if ( sha256HashStr != expectedSha256 ) { - Log_Report( pathRel, "Content sha256 doesn't match.", sha256HashStr, expectedSha256 ); + if ( sha1HashStr != expectedSha1 ) { + Log_Report( pathRel, "Content sha1 doesn't match.", sha1HashStr, expectedSha1 ); errors += 1; } @@ -146,7 +146,7 @@ auto verify( std::string_view root_, std::string_view indexLocation ) -> int { return 0; } -static auto verifyArchivedFile( const std::string& archivePath, const std::string& entryPath, std::uint64_t expectedSize, std::string_view expectedSha256, std::string_view expectedCrc32, unsigned int& entries, unsigned int& errors ) -> void { +static auto verifyArchivedFile( const std::string& archivePath, const std::string& entryPath, std::uint64_t expectedSize, std::string_view expectedSha1, std::string_view expectedCrc32, unsigned int& entries, unsigned int& errors ) -> void { using namespace vpkpp; static std::unordered_map> loadedVPKs{}; @@ -181,21 +181,21 @@ static auto verifyArchivedFile( const std::string& archivePath, const std::strin return; } - // sha256 (crc32 is already computed) - CryptoPP::SHA256 sha256er{}; - sha256er.Update( reinterpret_cast( entryData->data() ), entryData->size() ); - std::array sha256Hash{}; - sha256er.Final( sha256Hash.data() ); + // sha1 (crc32 is already computed) + CryptoPP::SHA1 sha1er{}; + sha1er.Update( reinterpret_cast( entryData->data() ), entryData->size() ); + std::array sha1Hash{}; + sha1er.Final( sha1Hash.data() ); - std::string sha256HashStr; + std::string sha1HashStr; std::string crc32HashStr; { - CryptoPP::StringSource sha256HashStrSink{ sha256Hash.data(), sha256Hash.size(), true, new CryptoPP::HexEncoder{ new CryptoPP::StringSink{ sha256HashStr } } }; + CryptoPP::StringSource sha1HashStrSink{ sha1Hash.data(), sha1Hash.size(), true, new CryptoPP::HexEncoder{ new CryptoPP::StringSink{ sha1HashStr } } }; CryptoPP::StringSource crc32HashStrSink{ reinterpret_cast( &entry->crc32 ), sizeof( entry->crc32 ), true, new CryptoPP::HexEncoder{ new CryptoPP::StringSink{ crc32HashStr } } }; } - if ( sha256HashStr != expectedSha256 ) { - Log_Report( fullPath, "Content sha256 doesn't match.", sha256HashStr, expectedSha256 ); + if ( sha1HashStr != expectedSha1 ) { + Log_Report( fullPath, "Content sha1 doesn't match.", sha1HashStr, expectedSha1 ); errors += 1; }