Skip to content

make the install script refuse what it cannot verify - #63

Merged
jonhadfield merged 3 commits into
mainfrom
fix/install-script-review
Sep 5, 2026
Merged

jonhadfield merged 3 commits into
mainfrom
fix/install-script-review

Conversation

@jonhadfield

Copy link
Copy Markdown
Owner

From the Copilot review of #62, which landed after it was merged. Four of the five points were fair; the first was a fault in the line the README tells people to run.

the documented command failed

CERTREADER_INSTALL_DIR pointing somewhere that does not exist yet — the ordinary state of ~/.local/bin — failed, and failed misleadingly:

certreader install: /home/u1/.local/bin is not writable and sudo is not available; set CERTREADER_INSTALL_DIR to somewhere you can write

The directory simply was not there. It is created now, with sudo only if it cannot be created otherwise.

My earlier test passed because it ran mkdir -p ~/bin first, so it tested a case the README does not describe. Testing the documented command verbatim is what found it.

unverified downloads were installed

Without sha256sum or shasum the script skipped verification and installed anyway, on a message to stderr. A script people are told to pipe into a shell does not get to skip the step that makes that defensible. It now stops.

Fixing that went wrong in its own way first: the failure was raised inside a subshell, so the user saw the mismatch message from the caller rather than the missing-tool one. The command is now settled before anything is downloaded, and the three ways verification can fail are distinct:

case message
no tool neither sha256sum nor shasum is available to check the download with
no entry in sums file checksums_linux_arm64.txt has no entry for certreader_0.25.1_linux_arm64.tar.gz
file does not match certreader_0.25.1_linux_arm64.tar.gz does not match its published checksum

None of them install anything.

also

Matching the archive within the sums file is by whole field (awk) rather than grep, where the dots in a filename are a pattern that could match a longer name. The brew note spells macOS the way Apple does, being a line somebody reads.

Not taken: capitalising "github" in a code comment. This repo writes comments in lowercase throughout (homebrew marks what a cask installs, goreleaser calls this deprecated), so the lowercase matches house style. The user-visible string was worth changing; the comment was not.

testing

amd64 and arm64 Debian containers: the README's own command with no directory present, no checksum tool, a sums file with no matching entry, and a tampered archive served through GITHUB_URL.

🤖 Generated with Claude Code

https://claude.ai/code/session_01WcPAJjNzG6bqy2FKqKKY1v

From the review of the merged change, and the first of these was a fault
in the line the README tells people to run.

CERTREADER_INSTALL_DIR pointing somewhere that does not exist yet, which
is the ordinary state of ~/.local/bin, failed. Worse, it failed saying
the directory was not writable and to pick one that was, which is not
what was wrong with it. The directory is created now, with sudo only if
it cannot be created otherwise. The earlier test of this passed because
it ran mkdir -p first, so it tested a case the README does not describe.

Without sha256sum or shasum the download went unchecked and was
installed anyway, on a shrug and a message to stderr. A script that
people are told to pipe into a shell does not get to skip the one step
that makes that defensible. It stops instead.

Which then went wrong in its own way: the failure was raised inside a
subshell, so what reached the user was the mismatch message from the
caller rather than the missing tool. The command is settled before
anything is downloaded now, and the three ways verification can fail say
which one happened: no tool to check with, no entry in the sums file for
this archive, or a file that does not match the entry. None of them
install anything.

Matching the archive in the sums file is by whole field rather than by
grep, where the dots in a filename are a pattern that could match a
longer name.

The note about brew now spells macOS the way apple does, being a line
somebody reads. The comments keep the lowercase this repo writes them
in.

Tested on amd64 and arm64: the README's own command with no directory
there, no checksum tool, a sums file with no matching entry, and a
tampered archive served through GITHUB_URL.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WcPAJjNzG6bqy2FKqKKY1v
Copilot AI lite review requested due to automatic review settings September 5, 2026 01:00

Copilot AI 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.

🟡 Changes recommended

checksum_command can return non-zero under set -e, causing an early exit before the intended “missing checksum tool” error is shown.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

This PR hardens the install one-liner by making the script refuse installation when it cannot verify a downloaded release artifact, and by correctly handling install directories that don’t exist yet (e.g., ~/.local/bin).

Changes:

  • Resolve and validate the checksum verification command before any downloads, and fail fast when no verifier is available.
  • Verify checksums using an exact filename match (field-based) rather than a regex match.
  • Create the install directory when missing, using sudo only when necessary.
File summaries
File Description
README.md Updates the Linux install docs to reflect directory creation and stricter verification behavior.
install Improves checksum verifier selection/handling, checksum line selection, and install-dir creation logic.
Review details
  • Files reviewed: 2/2 changed files
  • Comments generated: 2
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread install
Comment on lines +51 to +55
checksum_command() {
if command -v sha256sum >/dev/null 2>&1; then
sha256sum -c "$1"
echo "sha256sum -c"
elif command -v shasum >/dev/null 2>&1; then
shasum -a 256 -c "$1"
else
echo "neither sha256sum nor shasum found, skipping checksum" >&2
return 0
echo "shasum -a 256 -c"
Comment thread install Outdated
echo "${install_dir} does not exist, creating it"
if ! mkdir -p "${install_dir}" 2>/dev/null; then
command -v sudo >/dev/null 2>&1 ||
fail "${install_dir} does not exist and sudo is not available to create it"
jonhadfield and others added 2 commits September 5, 2026 02:04
The other install directory failures name the variable to set and this
one did not, so it told somebody what was wrong without telling them
what to do about it.

The comment on checksum_command now says why finding neither tool
returns zero rather than tripping set -e at the assignment, which is
the other thing the review raised. An if whose conditions are all false
and which has no else exits zero, so the empty answer reaches the
caller's check, which is what reports it. Confirmed in sh, bash and
dash, and by running the script with both tools hidden: it prints the
missing tool message and exits 1.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WcPAJjNzG6bqy2FKqKKY1v
The behaviour is unchanged: an if whose conditions are all false and
which has no else already exits zero, so the empty answer reached the
caller's check and the missing tool was reported there. Two passes of
review read the function as though it could end the script at the
assignment instead, which is reason enough to stop asking a reader to
know the rule. The return states it.

Still prints the missing tool message and exits 1 with both tools
hidden, and installs as before with them present.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WcPAJjNzG6bqy2FKqKKY1v
@jonhadfield
jonhadfield merged commit 7d86551 into main Sep 5, 2026
2 checks passed
@jonhadfield
jonhadfield deleted the fix/install-script-review branch September 5, 2026 01:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants