fix: reject '.' and leading '-' in party names

tmux session_check_name() silently rewrites '.' to '_', so a dotted
party name desyncs from its tmux session and every -t lookup fails
(verified on tmux 3.3a through 3.6b). Leading-dash names can never be
addressed through the CLI parsers.
This commit is contained in:
veg 2026-07-04 07:51:38 +00:00
parent a4e6dbe672
commit f06c599ea7
2 changed files with 37 additions and 17 deletions

39
party
View file

@ -65,30 +65,32 @@ EOF
# Helpers
# =======
# Validate a party name. Accepts [A-Za-z0-9._-]{1,63}. Reject empty,
# paths, shell metas, and overlong names: the name lands in a file
# path component, a tmux session name, and shell command lines.
# Validate a party name. Accepts [A-Za-z0-9_-]{1,63}, not starting with
# '-'. Reject empty, paths, shell metas, and overlong names: the name
# lands in a file path component, a tmux session name, and shell
# command lines. Dots are rejected because tmux's session_check_name()
# silently rewrites '.' (and ':') to '_', which would desync the party
# name from its tmux session and break every later `-t <name>` target.
# Leading '-' is rejected because every subcommand parser would eat the
# name as a flag, so such a party could never be addressed.
validate_party_name() {
name="$1"
case "$name" in
'' ) echo "party: name must not be empty" >&2; return 2 ;;
esac
# Length cap: 63 keeps the full /tmp/party-${USER}-${name} comfortably
# below the 108-char sun_path limit for typical USERs.
# Length cap: 63 keeps the full socket path comfortably below the
# 108-char sun_path limit for typical USERs.
if [ "${#name}" -gt 63 ]; then
echo "party: name '$name' too long (max 63 chars)" >&2
return 2
fi
case "$name" in
*[!A-Za-z0-9._-]* )
echo "party: name '$name' has invalid characters" >&2
echo " allowed: letters, digits, '.', '_', '-'" >&2
-* )
echo "party: name must not start with '-'" >&2
return 2 ;;
esac
# Reject ".", "..", and any leading-dot variant we don't want.
case "$name" in
.|.. )
echo "party: name '$name' is reserved" >&2
*[!A-Za-z0-9_-]* )
echo "party: name '$name' has invalid characters" >&2
echo " allowed: letters, digits, '_', '-'" >&2
return 2 ;;
esac
return 0
@ -237,10 +239,13 @@ roster_read() {
[ -n "$RR_PARTY_NAME" ] || return 1
# Pattern parity with cmd_host. The basename glob (party-*:*.d) is
# permissive, names like '.' (basename party-USER:..d) or 'a b'
# match the glob but validate_party_name rejects them. Run the
# canonical validator so the invariant cmd_host enforces on write
# is also checked on read.
# permissive — names like 'a b' or 'my.party' match the glob but
# validate_party_name rejects them (dots are banned: tmux rewrites
# them in session names). Run the canonical validator so the
# invariant cmd_host enforces on write is also checked on read.
# Side effect: pre-existing dotted-party dirs from older builds
# become undiscoverable, which is the pre-release migration policy
# (README §Status).
validate_party_name "$RR_PARTY_NAME" 2>/dev/null || return 1
# Both the dir and its sock must be owned by the user named in the