fix(bootstrap): report verify progress correctly past 2 GiB
The checksum and MD5 passes measured the file for their progress bar with fseek/ftell. On Windows a long is 32-bit, so ftell overflows on any archive larger than 2 GiB and hands back a wrong (often negative) size, which makes the verify progress percentage meaningless on exactly the multi-gigabyte downloads this code exists for. - Both passes now take the size from std::filesystem::file_size, which is 64-bit on every platform, through a small helper that returns 0 if the size can't be read. - No seek is performed just to size the file. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+11
-8
@@ -116,6 +116,13 @@ static std::uint64_t satAdd(std::uint64_t a, std::uint64_t b) {
|
||||
return (a > UINT64_MAX - b) ? UINT64_MAX : a + b;
|
||||
}
|
||||
|
||||
// fs::file_size is 64-bit on every platform; ftell() returns a 32-bit long on Win LLP64.
|
||||
static long long fileSizeOrZero(const std::string& path) {
|
||||
std::error_code ec;
|
||||
auto sz = fs::file_size(path, ec);
|
||||
return ec ? 0 : (long long)sz;
|
||||
}
|
||||
|
||||
static std::string lowerAscii(std::string s) {
|
||||
for (char& c : s)
|
||||
if (c >= 'A' && c <= 'Z') c = static_cast<char>(c - 'A' + 'a');
|
||||
@@ -924,10 +931,8 @@ std::string Bootstrap::computeSHA256(const std::string& filePath, float pctBase,
|
||||
FILE* fp = fopen(filePath.c_str(), "rb");
|
||||
if (!fp) return {};
|
||||
|
||||
// Get file size for progress reporting
|
||||
fseek(fp, 0, SEEK_END);
|
||||
long long fileSize = ftell(fp);
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
// File size for progress reporting (not a seek: ftell is 32-bit on Windows LLP64).
|
||||
const long long fileSize = fileSizeOrZero(filePath);
|
||||
|
||||
crypto_hash_sha256_state state;
|
||||
crypto_hash_sha256_init(&state);
|
||||
@@ -1061,10 +1066,8 @@ std::string Bootstrap::computeMD5(const std::string& filePath, float pctBase, fl
|
||||
FILE* fp = fopen(filePath.c_str(), "rb");
|
||||
if (!fp) return {};
|
||||
|
||||
// Get file size for progress reporting
|
||||
fseek(fp, 0, SEEK_END);
|
||||
long long fileSize = ftell(fp);
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
// File size for progress reporting (not a seek: ftell is 32-bit on Windows LLP64).
|
||||
const long long fileSize = fileSizeOrZero(filePath);
|
||||
|
||||
MD5Context ctx;
|
||||
md5_init(&ctx);
|
||||
|
||||
Reference in New Issue
Block a user