Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,10 @@ All notable changes to RigForge are documented here. The format is based on
read `[ "$port" -lt 1 ]`, and on a value bash cannot evaluate as an integer that returns an error
rather than false — so the check fell through, an unusable port reached the generated config, and
the operator got a raw shell diagnostic instead of the clear message the check exists to give. A
digit-count guard now runs first. The largest legal port is five digits, so nothing in range is
affected — with one exception worth knowing: a zero-padded port such as `:065535` used to be
accepted and is now rejected, and must be written without the padding.
digit-count guard now runs first. It keys on digit count and nothing else: the largest legal port
is five digits, so nothing in range is affected — except a port padded PAST five digits, such as
`:065535`, which used to be accepted and is now rejected. Padding that stays within five digits
(`:08080`) is unaffected and still accepted, as before.

- **A failed watchdog re-render no longer reports the change as applied (#395).** `install_watchdog`
ended on `systemctl enable ... || true`, so it returned success whatever had happened above it, and
Expand Down
13 changes: 8 additions & 5 deletions rigforge.sh
Original file line number Diff line number Diff line change
Expand Up @@ -398,12 +398,15 @@ _validate_host_port() { # <value> <label> <example-port>
_p="${_v##*:}"
# #405: the digit-count guard runs FIRST and short-circuits. On a value bash cannot evaluate as
# an integer, `[ "$_p" -lt 1 ]` returns 2 rather than false, so the range check fell through and
# let it pass. Any legal port is at most five digits, so nothing in range is rejected — with one
# exception: a zero-padded port (`065535`), which the range test evaluated as decimal and kept.
# It gets its OWN message, because the range wording would quote a value that IS in range and
# tell the operator nothing about what to change. Both cases asserted in tests/run.sh.
# let it pass. This keys on DIGIT COUNT and nothing else. Any legal port is at most five digits,
# so nothing in range is rejected — except a value padded PAST five digits (`065535`), which the
# range test evaluated as decimal and kept. Padding within five digits (`08080`) is untouched,
# accepted exactly as before, and pinned in tests/run.sh so that stays deliberate.
# It gets its OWN message: the range wording would quote a value that IS in range and tell the
# operator nothing. The message names the digit count, because the likeliest input to land here
# is a fat-fingered extra digit (`999999`) with no padding to remove.
if [ "${#_p}" -gt 5 ]; then
error "$_label port '$_p' in '$_v' must be 1-65535 written as plain digits, without padding."
error "$_label port '$_p' in '$_v' has more than five digits; a port is 1-65535."
fi
if [ "$_p" -lt 1 ] || [ "$_p" -gt 65535 ]; then
error "$_label port must be between 1 and 65535 (got '$_p' in '$_v')."
Expand Down
32 changes: 25 additions & 7 deletions tests/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -398,12 +398,12 @@ assert_rc "url port 65535 still accepted (#405)" "$?" "0"
c="$(mkconf p_s565535 "{ \"pools\": [{\"url\":\"h:3333\",\"socks5\":\"127.0.0.1:65535\"}] }")"
parse_rc "$c" "$ROOT"
assert_rc "socks5 port 65535 still accepted (#405)" "$?" "0"
# The digit-count guard is a real tightening on exactly one input: a zero-padded port. `[ 065535 -lt
# 1 ]` evaluates as decimal, so the old range test kept it. Pinned here because the CHANGELOG tells
# operators about it — an undocumented incidental rejection is how a fix becomes a surprise.
c="$(mkconf p_zeropad "{ \"pools\": [{\"url\":\"h:065535\"}] }")"
# The digit-count guard is a real tightening on exactly one shape: a value padded PAST five digits.
# `[ 065535 -lt 1 ]` evaluates as decimal, so the old range test kept it. Pinned here because the
# CHANGELOG tells operators about it — an undocumented incidental rejection is how a fix surprises.
c="$(mkconf p_over5 "{ \"pools\": [{\"url\":\"h:065535\"}] }")"
parse_rc "$c" "$ROOT"
assert_rc "zero-padded port rejected by the digit-count guard (#405)" "$?" "1"
assert_rc "port of more than five digits rejected (#405)" "$?" "1"
# Two guards, two messages: assert each on the sentence ONLY it writes, and that it does NOT emit the
# other's. Sharing one string is how deleting a guard outright leaves a suite green.
out="$( (
Expand All @@ -413,8 +413,26 @@ out="$( (
set +e
parse_config 2>&1
))"
assert_contains "zero-padded port names the padding (#405)" "$out" "without padding"
assert_absent "zero-padded port does not borrow the range guard's wording (#405)" "$out" "must be between 1 and 65535"
assert_contains "over-five-digit port names the digit count (#405)" "$out" "has more than five digits"
assert_absent "over-five-digit port does not borrow the range guard's wording (#405)" "$out" "must be between 1 and 65535"
# The guard keys on LENGTH, not on padding. A padded port WITHIN five digits is accepted exactly as
# it was before the fix. Pinned so the CHANGELOG's scope is tested rather than asserted in prose, and
# so tightening it later is a deliberate act with a red test, not a silent behaviour change.
c="$(mkconf p_pad_in5 "{ \"pools\": [{\"url\":\"h:08080\"}] }")"
parse_rc "$c" "$ROOT"
assert_rc "padding within five digits still accepted — the guard is length, not padding (#405)" "$?" "0"
# A fat-fingered extra digit is the likeliest input to reach this guard, and it carries no padding at
# all. It must get the digit-count message, never one telling it to remove padding it does not have.
c="$(mkconf p_fatfinger "{ \"pools\": [{\"url\":\"h:999999\"}] }")"
out="$( (
source "$SCRIPT"
CONFIG_JSON="$c"
SCRIPT_DIR="$ROOT"
set +e
parse_config 2>&1
))"
assert_contains "an unpadded over-long port names the digit count (#405)" "$out" "has more than five digits"
assert_absent "an unpadded over-long port is not told to remove padding (#405)" "$out" "padding"
c="$(mkconf p_nopools "{ }")"
parse_rc "$c" "$ROOT"
assert_rc "no pools rejected" "$?" "1"
Expand Down