From 893b686c1557b8244bcfafb22d0fc2f2eada1d4b Mon Sep 17 00:00:00 2001 From: atlas Date: Wed, 19 Aug 2026 20:25:38 +0200 Subject: [PATCH] fix(#3527): a missing source must report as zero, not as empty MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit argus, reviewing, ran the guard against a source path that does not exist rather than one that is empty. grep writes nothing to stdout in that case, so `|| true` left the count variable empty and the -eq test died with "integer expected" instead of reporting. The unit still failed — cat hits the same missing file and set -e stops it — but with a generic "no such file" rather than the message naming which half is absent, which is the only thing this guard is for. `|| echo 0` on all three counts. The gate gained the arm that was missing: an absent source, asserted to fail THROUGH the guard rather than merely to fail. --- nix/host-modules/lib/hive-ca-trust.nix | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/nix/host-modules/lib/hive-ca-trust.nix b/nix/host-modules/lib/hive-ca-trust.nix index eb0e3744..d6e5e428 100644 --- a/nix/host-modules/lib/hive-ca-trust.nix +++ b/nix/host-modules/lib/hive-ca-trust.nix @@ -181,19 +181,32 @@ in # nothing but public CAs is, for this purpose, an empty one that # measures as full. # - # `grep -c` exits 1 on zero matches and `set -e` is on, hence the - # `|| true` — without it the guard would die instead of reporting. - contributed=$(grep -c 'BEGIN CERTIFICATE' ${source} || true) + # One helper, because the safe form is not the obvious one and + # three copies of a subtle idiom is three chances to get it wrong. + # + # `grep -c` has two different zero-ish outcomes and `set -e` is + # on: an EMPTY file prints `0` and exits 1, a MISSING file prints + # nothing and exits 2. So `|| true` leaves the variable empty on + # the second — the `-eq` then dies with "integer expected" + # instead of reporting — and `|| echo 0` appends a second zero on + # the first, yielding `00`. Normalising afterwards is the only + # form that survives both. + certs() { + n=$(grep -c 'BEGIN CERTIFICATE' "$1" 2>/dev/null || true) + if [ -z "$n" ]; then n=0; fi + printf '%s' "$n" + } + contributed=$(certs ${source}) if [ "$contributed" -eq 0 ]; then echo "${unit}: ${source} contributed no certificate to the bundle" >&2 exit 1 fi - system=$(grep -c 'BEGIN CERTIFICATE' /etc/ssl/certs/ca-certificates.crt || true) + system=$(certs /etc/ssl/certs/ca-certificates.crt) cat /etc/ssl/certs/ca-certificates.crt ${source} > "$tmp" # `cat` of a source truncated between the count and the copy still # exits 0, so the result is checked against what both halves # brought rather than merely for being non-empty. - total=$(grep -c 'BEGIN CERTIFICATE' "$tmp" || true) + total=$(certs "$tmp") if [ "$total" -ne $((system + contributed)) ]; then echo "${unit}: bundle has $total certificates, expected $system + $contributed" >&2 exit 1