Skip to content

Commit 0f389ca

Browse files
committed
fix(server): robust output parsing and env var safety
why: - parse_output used strict=False which could silently hide truncated output - TMUX env var modification was not exception-safe - new test didn't verify all populated fields what: - Update parse_output to use strict=True after handling trailing separator - Wrap TMUX env var restoration in try/finally block - Add assertions for window_id and pane_id in new session test
1 parent 6530bfc commit 0f389ca

3 files changed

Lines changed: 40 additions & 30 deletions

File tree

src/libtmux/neo.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,13 @@ def parse_output(output: str) -> OutputRaw:
233233
False
234234
"""
235235
formats, _ = get_output_format()
236-
formatter = dict(zip(formats, output.split(FORMAT_SEPARATOR), strict=False))
236+
values = output.split(FORMAT_SEPARATOR)
237+
238+
# Remove the trailing empty string from the split
239+
if values and values[-1] == "":
240+
values = values[:-1]
241+
242+
formatter = dict(zip(formats, values, strict=True))
237243
return {k: v for k, v in formatter.items() if v}
238244

239245

src/libtmux/server.py

Lines changed: 31 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -539,48 +539,50 @@ def new_session(
539539
if env:
540540
del os.environ["TMUX"]
541541

542-
_fields, format_string = get_output_format()
542+
try:
543+
_fields, format_string = get_output_format()
543544

544-
tmux_args: tuple[str | int, ...] = (
545-
"-P",
546-
f"-F{format_string}",
547-
)
545+
tmux_args: tuple[str | int, ...] = (
546+
"-P",
547+
f"-F{format_string}",
548+
)
548549

549-
if session_name is not None:
550-
tmux_args += (f"-s{session_name}",)
550+
if session_name is not None:
551+
tmux_args += (f"-s{session_name}",)
551552

552-
if not attach:
553-
tmux_args += ("-d",)
553+
if not attach:
554+
tmux_args += ("-d",)
554555

555-
if start_directory:
556-
start_directory = pathlib.Path(start_directory).expanduser()
557-
tmux_args += ("-c", str(start_directory))
556+
if start_directory:
557+
start_directory = pathlib.Path(start_directory).expanduser()
558+
tmux_args += ("-c", str(start_directory))
558559

559-
if window_name:
560-
tmux_args += ("-n", window_name)
560+
if window_name:
561+
tmux_args += ("-n", window_name)
561562

562-
if x is not None:
563-
tmux_args += ("-x", x)
563+
if x is not None:
564+
tmux_args += ("-x", x)
564565

565-
if y is not None:
566-
tmux_args += ("-y", y)
566+
if y is not None:
567+
tmux_args += ("-y", y)
567568

568-
if environment:
569-
for k, v in environment.items():
570-
tmux_args += (f"-e{k}={v}",)
569+
if environment:
570+
for k, v in environment.items():
571+
tmux_args += (f"-e{k}={v}",)
571572

572-
if window_command:
573-
tmux_args += (window_command,)
573+
if window_command:
574+
tmux_args += (window_command,)
574575

575-
proc = self.cmd("new-session", *tmux_args)
576+
proc = self.cmd("new-session", *tmux_args)
576577

577-
if proc.stderr:
578-
raise exc.LibTmuxException(proc.stderr)
578+
if proc.stderr:
579+
raise exc.LibTmuxException(proc.stderr)
579580

580-
session_stdout = proc.stdout[0]
581+
session_stdout = proc.stdout[0]
581582

582-
if env:
583-
os.environ["TMUX"] = env
583+
finally:
584+
if env:
585+
os.environ["TMUX"] = env
584586

585587
session_data = parse_output(session_stdout)
586588

tests/test_server.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,8 @@ def test_new_session_returns_populated_session(server: Server) -> None:
109109
session = server.new_session(session_name="test_populated")
110110
assert session.session_id is not None
111111
assert session.session_name == "test_populated"
112+
assert session.window_id is not None
113+
assert session.pane_id is not None
112114

113115

114116
def test_new_session_no_name(server: Server) -> None:

0 commit comments

Comments
 (0)