perf(updater): read the downloaded archive in one bounded allocation
Before verifying a downloaded archive, both updaters slurped it into a string with an istreambuf_iterator, which grows the buffer repeatedly and reallocates as it reads a multi-megabyte file. It also placed no upper bound on the size it would read into memory. - A shared readFileExact helper sizes the file first and reads it in a single allocation, failing closed if the file is missing, empty, larger than a caller-supplied cap, or comes up short. A truncated read can never reach the SHA-256 / signature verifier. - Both updaters use it with the existing max-archive cap. Tests cover a good read, a read exactly at the cap, over the cap, an empty file, and a missing file. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -269,14 +269,8 @@ void XmrigUpdater::installResolved(const std::string& targetDir, const XmrigRele
|
||||
setProgress(State::Verifying, "Verifying download…");
|
||||
std::string bytes; // kept in scope through extraction so we extract the VERIFIED buffer (I-01)
|
||||
{
|
||||
std::ifstream f(zipPath, std::ios::binary);
|
||||
if (!f) {
|
||||
fs::remove(zipPath, ec);
|
||||
setProgress(State::Failed, "Could not read the downloaded archive.");
|
||||
return;
|
||||
}
|
||||
bytes.assign(std::istreambuf_iterator<char>(f), std::istreambuf_iterator<char>());
|
||||
if (f.bad()) {
|
||||
if (!readFileExact(zipPath, bytes,
|
||||
static_cast<std::uintmax_t>(kMaxArchiveBytes))) {
|
||||
fs::remove(zipPath, ec);
|
||||
setProgress(State::Failed, "Could not read the downloaded archive.");
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user