fix(wake): #942 harden WAKE_SNAPSHOT_TS_FUTURE_SLACK — validate shape AND force base-10
ci/woodpecker/push/publish Pipeline was successful
ci/woodpecker/push/ci Pipeline was successful

The slack knob was interpolated raw into $((...)) under set -u: a malformed value was FATAL to the poll, falsifying the poll-never-fails invariant, and a negative value inverted the guard to deny-all. Shape validation alone was insufficient — bash reads a leading zero as octal, so 08/09 passed the regex yet were fatal and 0300 silently meant 192. Now validated ^[0-9]{1,9}$ with a loud fallback to 300, then forced to base-10 via 10# so the knob means what the operator wrote.

Authored-by: pepper
Reviewed-by: mos-dt (independent, found both the original defect and the radix residual)
Merged-by: Mos
Co-authored-by: mos-dt-0 <[email protected]>
This commit was merged in pull request #942.
This commit is contained in:
2026-07-30 11:17:51 +00:00
committed by Mos
parent 8710d0f6d7
commit 3e47fc076f
3 changed files with 123 additions and 5 deletions
@@ -291,10 +291,24 @@ _poll_source() {
# Cross-host NTP skew of a few seconds is the NORMAL case, so allow a small
# slack; beyond it, drop the ts (the sha stays: independently verifiable).
if [ -n "$snap_ts" ]; then
local now_s
# The OPERATOR's knob gets the same discipline as the adapter's ts: it
# is interpolated into $((...)) under set -u, so a non-numeric value
# ('300s', '5m', 'abc') would be FATAL to the poll — the one thing this
# block must never be. Resolve it ONCE, validate, fall back loudly.
local now_s slack
slack="${WAKE_SNAPSHOT_TS_FUTURE_SLACK:-300}"
if ! printf '%s' "$slack" | grep -Eq '^[0-9]{1,9}$'; then
echo "detector.sh: WAKE_SNAPSHOT_TS_FUTURE_SLACK='$slack' is not a plain non-negative integer (seconds) — falling back to 300, poll continues (#940)." >&2
slack=300
fi
# Shape validation is not radix validation: bash reads a leading zero as
# OCTAL, so '08'/'09' pass the regex yet are FATAL in $((...)), and
# '0300' silently means 192. Force base-10 so the knob means what the
# operator wrote (safe: the regex above guarantees pure digits).
slack=$((10#$slack))
now_s="$(date +%s)"
if [ "$snap_ts" -gt $((now_s + ${WAKE_SNAPSHOT_TS_FUTURE_SLACK:-300})) ]; then
echo "detector.sh: source '$kind/$id' snapshot_ts is beyond the ${WAKE_SNAPSHOT_TS_FUTURE_SLACK:-300}s future-skew allowance (ts=$snap_ts now=$now_s) — snapshot_ts DROPPED, poll continues (#940)." >&2
if [ "$snap_ts" -gt $((now_s + slack)) ]; then
echo "detector.sh: source '$kind/$id' snapshot_ts is beyond the ${slack}s future-skew allowance (ts=$snap_ts now=$now_s) — snapshot_ts DROPPED, poll continues (#940)." >&2
snap_ts=""
fi
fi