codepoint-widths U+7FFFFFFF hangs the server
Issue description
Setting codepoint-widths to a code point equal to WCHAR_MAX hangs the tmux server on Linux with a signed 32-bit wchar_t:
set -g codepoint-widths U+7FFFFFFF=1
The option parser rejects values greater than WCHAR_MAX, but accepts WCHAR_MAX itself. The width-cache loop subsequently increments a wchar_t whose value is already WCHAR_MAX. This is signed integer overflow and is undefined behavior. With GCC on the platform below, the value wraps and the loop does not terminate.
Once this happens, the server consumes CPU and stops responding to clients, including kill-server.
This is the process of reproducing the problem.
tmux -Ltest kill-server 2>/dev/null
tmux -vv new
tmux -Ltest -f/dev/null new-session -d -s hang -x 80 -y 24 \
'exec sleep 3600'
pid=$(tmux -Ltest -f/dev/null display-message -p '#{pid}')
timeout 3 tmux -Ltest -f/dev/null set -g codepoint-widths U+1F600=2
echo control:$?
timeout 3 tmux -Ltest -f/dev/null set -g codepoint-widths U+7FFFFFFF=1
echo test:$?
kill -9 "$pid"
Expected output
control:0
test:0
Actual output:
control:0
test:124
Required information
Please provide the following information. These are required. Note that bug reports without logs may be ignored or closed without comment.
tmux version (tmux -V): tmux next-3.9 Platform (uname -sp): Linux x86_64 Terminal in use (xterm, rxvt, etc): VS Code integrated terminal (xterm.js) $TERM inside tmux (echo $TERM): xterm-256color $TERM outside tmux (echo $TERM): xterm-256color
- Logs from tmux (
tmux kill-server; tmux -vv new). I couldn't find theserver's log under the directory. Below are the logs of theclient.
1789454940.632499 client started (44862): version next-3.9, socket /tmp/tmux-1000/default, protocol 8
1789454940.632626 on Linux 7.0.0-30-generic #30~24.04.1-Ubuntu SMP PREEMPT_DYNAMIC Fri Aug 7 13:27:52 UTC 2
1789454940.632655 using libevent 2.1.12-stable poll
1789454940.633360 using ncurses 6.4 20240113
1789454940.634398 flags are 0x4018010000
1789454940.635638 socket is /tmp/tmux-1000/default
1789454940.636481 trying connect
1789454940.636673 add peer 0x64b40e868e90: 6 ((nil))
1789454940.638528 sending message 111 to peer 0x64b40e868e90 (8 bytes)
......
1789454940.692510 sending message 106 to peer 0x64b40e868e90 (0 bytes)
1789454940.692696 cmd_pack_argv: argv[0]=new
1789454940.692761 sending message 200 to peer 0x64b40e868e90 (8 bytes)
1789454940.692785 client loop enter
1789454940.765611 peer 0x64b40e868e90 message 207
1789454940.768182 sending message 208 to peer 0x64b40e868e90 (0 bytes)
1789455260.161082 peer 0x64b40e868e90 message 210
1789455260.161515 sending message 205 to peer 0x64b40e868e90 (0 bytes)
1789455260.179271 peer 0x64b40e868e90 message 204
1789455260.179789 client loop exit
Source: tmux/tmux