fix(installer): harden DownloadAndExtractStep per review

This commit is contained in:
Mika Kuns
2026-04-15 09:43:27 +02:00
parent c1e330164e
commit ea32a74baa
2 changed files with 16 additions and 3 deletions

View File

@@ -17,6 +17,9 @@ public sealed class DownloadAndExtractStep : IInstallStep
public async Task<StepResult> ExecuteAsync(InstallContext ctx, IProgress<string> progress, CancellationToken ct)
{
if (string.IsNullOrWhiteSpace(ctx.InstallDirectory))
return StepResult.Fail("Install directory is not set.");
progress.Report("Fetching latest release metadata...");
var release = await _releases.GetLatestReleaseAsync(ct);
if (release is null)
@@ -24,7 +27,7 @@ public sealed class DownloadAndExtractStep : IInstallStep
var zipAsset = release.Assets.FirstOrDefault(a =>
a.Name.StartsWith("ClaudeDo-", StringComparison.OrdinalIgnoreCase) &&
a.Name.EndsWith(".zip", StringComparison.OrdinalIgnoreCase));
a.Name.EndsWith("-win-x64.zip", StringComparison.OrdinalIgnoreCase));
var checksumAsset = release.Assets.FirstOrDefault(a =>
a.Name.Equals("checksums.txt", StringComparison.OrdinalIgnoreCase));
@@ -51,7 +54,7 @@ public sealed class DownloadAndExtractStep : IInstallStep
new Progress<long>(_ => { }), ct);
progress.Report("Verifying checksum...");
var map = ChecksumVerifier.ParseChecksumsFile(File.ReadAllText(checksumPath));
var map = ChecksumVerifier.ParseChecksumsFile(await File.ReadAllTextAsync(checksumPath, ct));
if (!map.TryGetValue(zipAsset.Name, out var expectedHash))
return StepResult.Fail($"No checksum entry for {zipAsset.Name} in checksums.txt.");
if (!ChecksumVerifier.Verify(zipPath, expectedHash))
@@ -66,7 +69,16 @@ public sealed class DownloadAndExtractStep : IInstallStep
progress.Report("Extracting...");
Directory.CreateDirectory(ctx.InstallDirectory);
ZipFile.ExtractToDirectory(zipPath, ctx.InstallDirectory, overwriteFiles: true);
try
{
ZipFile.ExtractToDirectory(zipPath, ctx.InstallDirectory, overwriteFiles: true);
}
catch (Exception ex)
{
return StepResult.Fail(
$"Extraction failed after old binaries were removed: {ex.Message}. " +
"Your install directory may be incomplete. Re-run the installer to retry.");
}
ctx.InstalledVersion = release.TagName.TrimStart('v', 'V');
return StepResult.Ok();