fix(wake): #942 review — force base-10 on the slack knob; shape validation is not radix validation
ci/woodpecker/pr/ci Pipeline was successful
ci/woodpecker/pr/ci Pipeline was successful
'08'/'09' pass ^[0-9]{1,9}$ yet are fatal octal in $((...)) — the same
poll-killing mode this PR closes — and '0300' silently means 192, changing the
operator's stated intent with no warning. slack=$((10#$slack)) after the
regex (which guarantees pure digits, so 10# is safe) makes zero-padded knobs
mean what was written instead of rejecting them. Two new D13 sub-cases: '08'
survives with metadata kept, and the discrimination test — '0300' with a ts
+250s ahead KEEPS the ts (decimal 300) where octal 192 would have dropped it.
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01NsKce8iZuSuRnu3gVMCBKB
This commit is contained in:
co-authored by
Claude Fable 5
parent
313f3087e6
commit
667402457e
@@ -301,6 +301,11 @@ _poll_source() {
|
||||
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 + 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
|
||||
|
||||
@@ -279,7 +279,12 @@
|
||||
# gets the same discipline (#941 §2 round 2): validated
|
||||
# ^[0-9]{1,9}$, else LOUD fallback to 300 — a malformed knob
|
||||
# ('300s', '5m', 'abc') must never kill the poll, and a negative
|
||||
# one must never invert the guard into deny-all. SKEW GUARANTEE
|
||||
# one must never invert the guard into deny-all. Shape validation
|
||||
# is NOT radix validation (#942 review): bash reads leading zeros
|
||||
# as OCTAL, so '08'/'09' pass the regex yet are fatal in $((...))
|
||||
# and '0300' silently means 192 — the knob is therefore forced
|
||||
# base-10 (10#) after validation, so it means what the operator
|
||||
# wrote. SKEW GUARANTEE
|
||||
# (stated, not implied): the future-skew check runs against the
|
||||
# DETECTOR's clock; consumer-side age arithmetic runs on the
|
||||
# consumer's. A surviving snapshot_ts is therefore attested only
|
||||
|
||||
@@ -644,6 +644,24 @@ EOF
|
||||
entry="$("$STORE" drain | tail -1)"
|
||||
echo "$entry" | jq -e --arg s "$goodsha" 'select(.locators.snapshot_sha==$s) | .locators | has("snapshot_ts")' >/dev/null 2>&1 \
|
||||
|| fail_msg "D13: negative slack must NOT invert the guard into deny-all [$entry]"
|
||||
# (d2-pre) ZERO-PADDED knobs — shape-valid, radix-hostile. '08' passes the
|
||||
# regex but is fatal octal in \$((...)) without the 10# normalization; '0300'
|
||||
# silently means 192 (octal), so a ts +250s ahead would be WRONGLY dropped.
|
||||
# With 10#: '08' means 8 and survives; '0300' means 300 and the +250s ts is KEPT.
|
||||
printf '{"snapshot_sha":"%s","snapshot_ts":%s}\n' "$goodsha" "$(date +%s)" >"$stub/repo_r1.meta"
|
||||
printf 'SHA-DD2\n' >"$stub/repo_r1"
|
||||
err="$(WAKE_SNAPSHOT_TS_FUTURE_SLACK='08' "$DET" poll-once 2>&1 >/dev/null)"; rc=$?
|
||||
[ "$rc" -eq 0 ] || fail_msg "D13: SLACK='08' (octal-fatal without 10#) must NEVER fail the poll (rc=$rc) [$err]"
|
||||
entry="$("$STORE" drain | tail -1)"
|
||||
echo "$entry" | jq -e --arg s "$goodsha" 'select(.locators.snapshot_sha==$s) | .locators | has("snapshot_ts")' >/dev/null 2>&1 \
|
||||
|| fail_msg "D13: SLACK='08' with a current ts must keep the metadata [$entry]"
|
||||
printf '{"snapshot_sha":"%s","snapshot_ts":%s}\n' "$goodsha" "$(( $(date +%s) + 250 ))" >"$stub/repo_r1.meta"
|
||||
printf 'SHA-DD3\n' >"$stub/repo_r1"
|
||||
err="$(WAKE_SNAPSHOT_TS_FUTURE_SLACK='0300' "$DET" poll-once 2>&1 >/dev/null)"; rc=$?
|
||||
[ "$rc" -eq 0 ] || fail_msg "D13: SLACK='0300' must not fail the poll (rc=$rc)"
|
||||
entry="$("$STORE" drain | tail -1)"
|
||||
echo "$entry" | jq -e --arg s "$goodsha" 'select(.locators.snapshot_sha==$s) | .locators | has("snapshot_ts")' >/dev/null 2>&1 \
|
||||
|| fail_msg "D13: SLACK='0300' must mean 300 (decimal), so a +250s ts is KEPT — octal 192 would have dropped it [$entry]"
|
||||
# (d) a VALID knob is still honored: slack=0 with a ts 60s ahead -> future-skew drop.
|
||||
printf '{"snapshot_sha":"%s","snapshot_ts":%s}\n' "$goodsha" "$(( $(date +%s) + 60 ))" >"$stub/repo_r1.meta"
|
||||
printf 'SHA-EEE\n' >"$stub/repo_r1"
|
||||
@@ -653,7 +671,7 @@ EOF
|
||||
entry="$("$STORE" drain | tail -1)"
|
||||
echo "$entry" | jq -e --arg s "$goodsha" 'select(.locators.snapshot_sha==$s) | .locators | has("snapshot_ts") | not' >/dev/null 2>&1 \
|
||||
|| fail_msg "D13: valid SLACK=0 must drop the future ts but keep the sha [$entry]"
|
||||
[ "$(det_seq)" = "4" ] || fail_msg "D13: all four real deltas must still have enqueued, got seq $(det_seq)"
|
||||
[ "$(det_seq)" = "6" ] || fail_msg "D13: all six real deltas must still have enqueued, got seq $(det_seq)"
|
||||
) && ok
|
||||
|
||||
echo
|
||||
|
||||
Reference in New Issue
Block a user