diff --git a/cf b/cf index c6f36a9..dfd08aa 100755 --- a/cf +++ b/cf @@ -230,7 +230,10 @@ case "$CMD" in [ -z "$1" ] && { echo "Usage: cf send \"message\"" >&2; exit 1; } load_session [ -z "$JOINED" ] && { echo "Must join first: cf join" >&2; exit 1; } - printf '%s: %s\n' "$MYNAME" "$1" >> "$CHATFILE" + # Collapse newlines so one send stays one line — the "Name: msg" invariant + # that read/await depend on. A literal newline would otherwise land as a + # prefix-less second line that await parses as a phantom sender. + printf '%s: %s\n' "$MYNAME" "${1//$'\n'/ }" >> "$CHATFILE" ;; await|a|wait|w) @@ -248,7 +251,7 @@ case "$CMD" in [ -z "$1" ] && { echo "Usage: cf send-await \"message\"" >&2; exit 1; } load_session [ -z "$JOINED" ] && { echo "Must join first: cf join" >&2; exit 1; } - printf '%s: %s\n' "$MYNAME" "$1" >> "$CHATFILE" + printf '%s: %s\n' "$MYNAME" "${1//$'\n'/ }" >> "$CHATFILE" tail -f -n 0 "$CHATFILE" | head -n 1 ;; diff --git a/test_cf.sh b/test_cf.sh index 3a7e24d..4a96180 100755 --- a/test_cf.sh +++ b/test_cf.sh @@ -542,6 +542,28 @@ test_special_characters_in_message() { teardown } +test_send_collapses_newlines() { + # Regression: a multi-line `send` arg must stay one physical line, or + # read/await misparse the wrapped text as a phantom sender (it has no + # "Name:" prefix). Newlines collapse to spaces. + setup + "$CF_PATH" create-room 2>/dev/null || true + local name rc=0 before after last + name=$("$CF_PATH" register Chatfile) + "$CF_PATH" join >/dev/null + before=$(wc -l < Chatfile) + "$CF_PATH" send "line one +line two" + after=$(wc -l < Chatfile) + last=$(tail -n 1 Chatfile) + if [ "$((after - before))" -ne 1 ] || [ "$last" != "$name: line one line two" ]; then + echo " multi-line send not collapsed: +$((after - before)) line(s), last='$last'" >&2 + rc=1 + fi + teardown + return $rc +} + test_multiline_preserved() { setup "$CF_PATH" create-room 2>/dev/null || true @@ -685,6 +707,7 @@ 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 "send collapses newlines (one-line invariant)" test_send_collapses_newlines run_test "multiline preserved" test_multiline_preserved echo ""