diff --git a/arcup/arcup b/arcup/arcup index 3590cd36..999bc2b2 100755 --- a/arcup/arcup +++ b/arcup/arcup @@ -656,7 +656,12 @@ verify_checksum_file() { local archive_name="$3" local expected_checksum expected_name actual_checksum - if ! read -r expected_checksum expected_name < "$checksum_path"; then + # `read` returns non-zero when it hits EOF before a newline, even though it + # still populates the variables. A checksum file whose single line has no + # trailing newline is valid, so decide emptiness from the parsed hash rather + # than from read's exit status. + read -r expected_checksum expected_name < "$checksum_path" || true + if [[ -z "$expected_checksum" ]]; then error "Checksum file is empty: $checksum_path" fi diff --git a/arcup/test_arcup.sh b/arcup/test_arcup.sh index 49021191..cb56b648 100755 --- a/arcup/test_arcup.sh +++ b/arcup/test_arcup.sh @@ -119,6 +119,20 @@ test_checksum_validation() { printf '%s other-asset.tar.gz\n' "$checksum" > "$checksum_file" expect_fail "checksum filename mismatch fails" verify_checksum_file "$archive" "$checksum_file" "$archive_name" + + # A checksum file whose only line has no trailing newline is still valid. + printf '%s %s' "$checksum" "$archive_name" > "$checksum_file" + verify_checksum_file "$archive" "$checksum_file" "$archive_name" + pass "checksum file without trailing newline passes" + + # A genuinely empty checksum file must still be rejected. + : > "$checksum_file" + expect_fail "empty checksum file fails" verify_checksum_file "$archive" "$checksum_file" "$archive_name" + + # A wrong hash without a trailing newline must still fail the comparison, + # not slip through the emptiness check. + printf '%s %s' "0000000000000000000000000000000000000000000000000000000000000000" "$archive_name" > "$checksum_file" + expect_fail "mismatched checksum without trailing newline fails" verify_checksum_file "$archive" "$checksum_file" "$archive_name" } test_download_error_lists_assets() {