Reporting this as an issue first, per CONTRIBUTING. I opened it as a PR before reading the contribution policy, which was my mistake; those PRs (#402, #418) are closed and I am not reopening anything without an assignment.
What happens
verify_checksum_file decides whether the checksum file is empty from the exit status of read (arcup/arcup:659 on main):
if ! read -r expected_checksum expected_name < "$checksum_path"; then
error "Checksum file is empty: $checksum_path"
read returns non-zero at EOF even when it successfully populated the variables, which is exactly what a single line with no trailing newline produces. On bash 5.2.21:
$ printf 'abc name' > nl.txt
$ if ! read -r a b < nl.txt; then echo "READ FAILED, a=[$a] b=[$b]"; fi
READ FAILED, a=[abc] b=[name]
So a perfectly valid checksum file is rejected, and the operator is told the file is empty when it is not.
A second, more reachable problem in the same function
If $checksum_path does not exist or is unreadable, the redirection error leaks to the user and then set -u aborts on the unset variable:
arcup/arcup: line 659: /path/to/absent.sha256: No such file or directory
arcup/arcup: line 661: expected_checksum: unbound variable
Two confusing messages where one clear one would do.
Reachability, stated honestly
No official release can trigger the newline bug. scripts/release-package.sh:31-34 writes the file with sha256sum or shasum -a 256, both of which always emit a trailing newline, and arcup has no offline install mode. It is reachable through ARC_REPO pointing at a third-party release, or a mirror serving its own assets via GITHUB_API_URL.
The missing-file message above is reachable on any path, so that is the part with actual user impact.
Environment
bash 5.2.21, Linux. arcup at ARCUP_INSTALLER_VERSION="0.2.0".
Note on the fix, if you want one
I have a patch ready and tested: inspect the parsed value instead of the exit status, add a [[ ! -r ]] guard, and five cases in arcup/test_arcup.sh (30/30 pass). Three of those cases assert the error message rather than just a non-zero exit, because all three also fail on main for the wrong reasons and would otherwise be characterization tests.
It would also need ARCUP_INSTALLER_VERSION bumped, since self_update gates on version_gt (lines 423 and 452) and an unchanged version means existing installs answer "already up to date" and never pick the fix up.
Happy to open a PR if you assign this to me, or to just leave the description here if you would rather fix it yourselves. Either is fine.
Reporting this as an issue first, per CONTRIBUTING. I opened it as a PR before reading the contribution policy, which was my mistake; those PRs (#402, #418) are closed and I am not reopening anything without an assignment.
What happens
verify_checksum_filedecides whether the checksum file is empty from the exit status ofread(arcup/arcup:659onmain):readreturns non-zero at EOF even when it successfully populated the variables, which is exactly what a single line with no trailing newline produces. On bash 5.2.21:So a perfectly valid checksum file is rejected, and the operator is told the file is empty when it is not.
A second, more reachable problem in the same function
If
$checksum_pathdoes not exist or is unreadable, the redirection error leaks to the user and thenset -uaborts on the unset variable:Two confusing messages where one clear one would do.
Reachability, stated honestly
No official release can trigger the newline bug.
scripts/release-package.sh:31-34writes the file withsha256sumorshasum -a 256, both of which always emit a trailing newline, andarcuphas no offline install mode. It is reachable throughARC_REPOpointing at a third-party release, or a mirror serving its own assets viaGITHUB_API_URL.The missing-file message above is reachable on any path, so that is the part with actual user impact.
Environment
bash 5.2.21, Linux.
arcupatARCUP_INSTALLER_VERSION="0.2.0".Note on the fix, if you want one
I have a patch ready and tested: inspect the parsed value instead of the exit status, add a
[[ ! -r ]]guard, and five cases inarcup/test_arcup.sh(30/30 pass). Three of those cases assert the error message rather than just a non-zero exit, because all three also fail onmainfor the wrong reasons and would otherwise be characterization tests.It would also need
ARCUP_INSTALLER_VERSIONbumped, sinceself_updategates onversion_gt(lines 423 and 452) and an unchanged version means existing installs answer "already up to date" and never pick the fix up.Happy to open a PR if you assign this to me, or to just leave the description here if you would rather fix it yourselves. Either is fine.