Skip to content

fix: verify downloaded files before completion#3040

Open
lhx077 wants to merge 1 commit into
devfrom
codex/fix-hash-verification-for-downloaded-artifacts
Open

fix: verify downloaded files before completion#3040
lhx077 wants to merge 1 commit into
devfrom
codex/fix-hash-verification-for-downloaded-artifacts

Conversation

@lhx077

@lhx077 lhx077 commented Jun 6, 2026

Copy link
Copy Markdown
Member

Motivation

  • The loader previously validated only existing files and did not verify freshly downloaded content, which allows a malicious mirror to supply modified artifacts that are accepted as valid.
  • Callers supply ModBase.FileChecker (expected size/hash) for sensitive artifacts such as Minecraft libraries and assets, so downloads must be re-checked after being written.

Description

  • Re-introduce post-download integrity verification by invoking file.Check?.Check(file.LocalPath) immediately after FileDownloader.Download(...) in LoaderDownload.ProcessFileAsync of Plain Craft Launcher 2/Modules/Network/Loaders/LoaderDownload.cs.
  • Treat a non-null check result as a failure by throwing an IOException with the checker message, which routes the error through the existing retry/failure handling path.
  • Preserve the existing retry loop and file state updates so normal successful downloads continue to be marked Finished after verification.

Testing

  • Ran a small Python assertion that checks the post-download call to file.Check?.Check(file.LocalPath) is present before the Finished state, and the assertion passed.
  • Ran git diff --check to ensure no whitespace errors and it passed.
  • Attempted dotnet build 'Plain Craft Launcher 2/Plain Craft Launcher 2.csproj' -c Debug --no-restore but it could not be executed in this environment because dotnet is not installed.

Codex Task

Summary by Sourcery

Bug Fixes:

  • 确保新下载的文件在被标记为成功下载之前,会根据其配置的文件检查规则重新进行验证。
Original summary in English

Summary by Sourcery

Bug Fixes:

  • Ensure freshly downloaded files are re-validated against their configured file checks before being marked as successfully downloaded.

@pcl-ce-automation pcl-ce-automation Bot added 🛠️ 等待审查 Pull Request 已完善,等待维护者或负责人进行代码审查 size: XS PR 大小评估:微型 and removed codex labels Jun 6, 2026
@sourcery-ai

sourcery-ai Bot commented Jun 6, 2026

Copy link
Copy Markdown
审阅者指南(在小型 PR 上折叠)

审阅者指南

为每个已下载文件增加下载后的完整性校验:在下载完成后立即重新检查文件,如果校验返回错误则使整个操作失败,从而在保留现有重试与状态处理逻辑的同时,拒绝受损或被篡改的制品。

文件级变更

变更 详情 文件
添加下载后的完整性检查,并通过现有重试逻辑处理失败情况。
  • FileDownloader.Download 完成后,立即调用文件的校验器(如果存在),并传入本地文件路径。
  • 捕获校验器的返回值,将任何非空结果视为校验失败。
  • 当校验失败时抛出带有描述性消息的 IOException,以便现有的捕获/重试流水线在将文件标记为完成之前处理该失败。
Plain Craft Launcher 2/Modules/Network/Loaders/LoaderDownload.cs

提示与命令

与 Sourcery 交互

  • 触发新的审阅: 在 pull request 中发表评论 @sourcery-ai review
  • 继续讨论: 直接回复 Sourcery 的审阅评论。
  • 从审阅评论生成 GitHub issue: 通过回复某条审阅评论来请求 Sourcery 从该评论创建一个 issue。你也可以回复该评论 @sourcery-ai issue 来从中创建一个 issue。
  • 生成 pull request 标题: 在 pull request 标题的任意位置写上 @sourcery-ai,即可随时生成标题。你也可以在 pull request 中评论 @sourcery-ai title 来(重新)生成标题。
  • 生成 pull request 摘要: 在 pull request 描述正文的任意位置写上 @sourcery-ai summary,即可在你想要的位置随时生成 PR 摘要。你也可以在 pull request 中评论 @sourcery-ai summary 来(重新)生成摘要。
  • 生成审阅者指南: 在 pull request 中评论 @sourcery-ai guide,即可随时(重新)生成审阅者指南。
  • 解决所有 Sourcery 评论: 在 pull request 中评论 @sourcery-ai resolve,即可解决所有 Sourcery 评论。如果你已经处理完所有评论且不想再看到它们,这将非常有用。
  • 撤销所有 Sourcery 审阅: 在 pull request 中评论 @sourcery-ai dismiss,即可撤销所有现有的 Sourcery 审阅。尤其适用于你想从头开始新的审阅时 —— 别忘了再评论 @sourcery-ai review 来触发新一轮审阅!

自定义你的体验

访问你的控制面板以:

  • 启用或禁用审阅功能,例如 Sourcery 生成的 pull request 摘要、审阅者指南等。
  • 更改审阅语言。
  • 添加、移除或编辑自定义审阅说明。
  • 调整其他审阅设置。

获取帮助

Original review guide in English
Reviewer's guide (collapsed on small PRs)

Reviewer's Guide

Adds post-download integrity verification for each downloaded file by re-checking it immediately after download and failing the operation if verification returns an error, so that compromised or corrupted artifacts are rejected while preserving the existing retry and state-handling logic.

File-Level Changes

Change Details Files
Add post-download integrity check and route failures through existing retry logic.
  • Invoke the file’s checker (if present) immediately after FileDownloader.Download completes, passing the local file path.
  • Capture the checker’s return value and interpret any non-null result as a verification failure.
  • Throw an IOException with a descriptive message when verification fails so the existing catch/retry pipeline handles the failure before marking the file as finished.
Plain Craft Launcher 2/Modules/Network/Loaders/LoaderDownload.cs

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - 我在这里给出了一些整体性的反馈:

  • 当完整性检查失败时,可以考虑在重新抛出异常之前删除部分/错误下载的文件,这样后续重试时就不会一直验证同一个有问题的构件。
  • 在抛出的 IOException 中使用的硬编码中文错误信息,可能更适合通过你现有的本地化机制或常量来表达,以保持应用内错误信息的一致性。
  • 你可能需要在 IOException 的错误信息中加入更多上下文信息(例如 file.LocalPath 或具有代表性的 URL),以便在日志中更容易诊断到底是哪个文件验证失败。
给 AI 代理的提示
Please address the comments from this code review:

## Overall Comments
- When the integrity check fails, consider deleting the partially/incorrectly downloaded file before rethrowing so subsequent retries don’t keep validating the same bad artifact.
- The hard-coded Chinese error message in the thrown IOException may be better expressed via your existing localization mechanism or a constant, to keep error messaging consistent across the app.
- You might want to include more context (e.g., file.LocalPath or a representative URL) in the IOException message to make diagnosing which file failed verification easier in logs.

Sourcery 对开源项目是免费的——如果你觉得我们的评审有帮助,欢迎分享 ✨
帮我变得更有用!请对每条评论点 👍 或 👎,我会根据这些反馈改进为你提供的评审。
Original comment in English

Hey - I've left some high level feedback:

  • When the integrity check fails, consider deleting the partially/incorrectly downloaded file before rethrowing so subsequent retries don’t keep validating the same bad artifact.
  • The hard-coded Chinese error message in the thrown IOException may be better expressed via your existing localization mechanism or a constant, to keep error messaging consistent across the app.
  • You might want to include more context (e.g., file.LocalPath or a representative URL) in the IOException message to make diagnosing which file failed verification easier in logs.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- When the integrity check fails, consider deleting the partially/incorrectly downloaded file before rethrowing so subsequent retries don’t keep validating the same bad artifact.
- The hard-coded Chinese error message in the thrown IOException may be better expressed via your existing localization mechanism or a constant, to keep error messaging consistent across the app.
- You might want to include more context (e.g., file.LocalPath or a representative URL) in the IOException message to make diagnosing which file failed verification easier in logs.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 906d16a9e9

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +140 to +142
var checkError = file.Check?.Check(file.LocalPath);
if (checkError is not null)
throw new IOException($"下载文件校验失败:{checkError}");

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Try alternate mirrors after checksum failures

When the first URL returns a complete but invalid file, this check throws only after FileDownloader.Download(...) has already returned; DownloadCoreAsync stops at the first transport-successful URL (FileDownloader.cs lines 51-57), so the exception is caught by the outer retry loop and the same first URL is retried up to four times instead of falling through to later mirrors. For multi-source downloads where mirror 1 is corrupt or malicious but mirror 2 is valid, this makes the whole download fail despite an available good source; the integrity check needs to participate in the per-URL failure path or otherwise advance to the next URL.

Useful? React with 👍 / 👎.

@whitecat346 whitecat346 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

出错后删除异常文件

Copy link
Copy Markdown
Member

⚠️ 签名提示

你的一个或多个 Commit 存在无效的签名!
根据 Repo Rules 约定,未持有有效签名的 Pull Request 将无法被合并

帮助我改进!如果我的回答与实际情况不符,请点按 👎 并继续提供反馈。
CSharpen Sapi v0.0.1 | Diag Id: cBYqHXf2pfEUGVYymwkNXxL73C3BWcic

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size: XS PR 大小评估:微型 🛠️ 等待审查 Pull Request 已完善,等待维护者或负责人进行代码审查

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants