diff --git a/cf b/cf index a84a95d..c6f36a9 100755 --- a/cf +++ b/cf @@ -184,9 +184,18 @@ case "$CMD" in suffix=$((RANDOM % 9000 + 1000)) MYNAME="${adj}-${noun}-${suffix}" grep -q "^${MYNAME}:" "$CHATFILE" 2>/dev/null || break - ((attempts++)) + # NB: `((attempts++))` evaluates to the *old* value, so on the first + # iteration it yields 0 — which bash reports as exit status 1, and + # under `set -e` (above) that aborted the whole script on the very + # first name collision. An assignment always returns success. + attempts=$((attempts + 1)) done + if [ "$attempts" -ge 100 ]; then + echo "Failed to generate a unique name after 100 attempts" >&2 + exit 1 + fi + JOINED="" # Global rooms get a HOME-level session so any working directory can find it. # Local rooms get a CWD-level session (directory-scoped). diff --git a/test_cf.sh b/test_cf.sh index f1214f8..3a7e24d 100755 --- a/test_cf.sh +++ b/test_cf.sh @@ -489,6 +489,30 @@ test_help_flag() { # Edge Case Tests # ============================================================================ +test_register_survives_name_collisions() { + # Regression: `cf register`'s retry loop used `((attempts++))`, which under + # `set -e` aborts the whole script on the FIRST name collision (((0++)) + # yields exit status 1). Fill a chunk of the name space so RANDOM collides + # often, then register many times — every one must still succeed. + setup + "$CF_PATH" create-room 2>/dev/null || true + awk 'BEGIN{ + split("swift bold calm keen sage wild bright dark quick slow", a, " "); + split("fox owl raven wolf bear hawk crane lynx deer hare", n, " "); + for (i=1;i<=10;i++) for (j=1;j<=10;j++) for (s=1000;s<2800;s++) + printf "%s-%s-%d: taken\n", a[i], n[j], s + }' >> Chatfile + + local rc=0 i name + for i in $(seq 1 30); do + rm -f .cf_session + name=$("$CF_PATH" register Chatfile 2>/dev/null) || { rc=1; break; } + [ -n "$name" ] || { rc=1; break; } + done + teardown + return $rc +} + test_username_uniqueness() { setup "$CF_PATH" create-room 2>/dev/null || true @@ -658,6 +682,7 @@ run_test "help flag" test_help_flag echo "" echo "Edge Case Tests:" +run_test "register survives name collisions (set -e)" test_register_survives_name_collisions run_test "username uniqueness" test_username_uniqueness run_test "special characters in message" test_special_characters_in_message run_test "multiline preserved" test_multiline_preserved