Skip to content

Commit

Permalink
Merge pull request #9 from StrataSource/feat/vpks-2
Browse files Browse the repository at this point in the history
fix: normalize slashes of stored vpk paths
  • Loading branch information
ENDERZOMBI102 authored Jul 20, 2024
2 parents c0843d8 + e81bd26 commit 550191a
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 40 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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 )
Expand Down
35 changes: 18 additions & 17 deletions src/create.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 ) {
Expand Down Expand Up @@ -120,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<CryptoPP::byte, CryptoPP::SHA256::DIGESTSIZE> sha256Hash{};
sha256er.Final( sha256Hash.data() );
std::array<CryptoPP::byte, CryptoPP::SHA1::DIGESTSIZE> sha1Hash{};
sha1er.Final( sha1Hash.data() );
std::array<CryptoPP::byte, CryptoPP::CRC32::DIGESTSIZE> 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;
}
Expand Down Expand Up @@ -192,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<const CryptoPP::byte*>( entryData->data() ), entryData->size() );
std::array<CryptoPP::byte, CryptoPP::SHA256::DIGESTSIZE> sha256Hash{};
sha256er.Final( sha256Hash.data() );
// sha1 (crc32 is already computed)
CryptoPP::SHA1 sha1er{};
sha1er.Update( reinterpret_cast<const CryptoPP::byte*>( entryData->data() ), entryData->size() );
std::array<CryptoPP::byte, CryptoPP::SHA1::DIGESTSIZE> 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<const CryptoPP::byte*>( &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 );
}
}
Expand Down
44 changes: 22 additions & 22 deletions src/verify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<std::string>;

Expand Down Expand Up @@ -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
Expand All @@ -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;
}

Expand Down Expand Up @@ -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<CryptoPP::byte, CryptoPP::SHA256::DIGESTSIZE> sha256Hash{};
sha256er.Final( sha256Hash.data() );
std::array<CryptoPP::byte, CryptoPP::SHA1::DIGESTSIZE> sha1Hash{};
sha1er.Final( sha1Hash.data() );
std::array<CryptoPP::byte, CryptoPP::CRC32::DIGESTSIZE> 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;
}

Expand All @@ -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<std::string, std::unique_ptr<PackFile>> loadedVPKs{};
Expand Down Expand Up @@ -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<const CryptoPP::byte*>( entryData->data() ), entryData->size() );
std::array<CryptoPP::byte, CryptoPP::SHA256::DIGESTSIZE> sha256Hash{};
sha256er.Final( sha256Hash.data() );
// sha1 (crc32 is already computed)
CryptoPP::SHA1 sha1er{};
sha1er.Update( reinterpret_cast<const CryptoPP::byte*>( entryData->data() ), entryData->size() );
std::array<CryptoPP::byte, CryptoPP::SHA1::DIGESTSIZE> 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<const CryptoPP::byte*>( &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;
}

Expand Down

0 comments on commit 550191a

Please sign in to comment.