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:
2026-10-13 20:57:21 -05:00
co-authored by Claude Opus 4.8
parent e1003cba43
commit b3a1a9e654
+11 -8
View File
@@ -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);