Filter DA1 responses from replay buffer on WebSocket connect

The replay buffer can contain DA1/DA2 terminal attribute responses
(e.g., \x1b[?1;10;0c) that were captured before filtering was added
to the session classes. These responses appear as visible text like
'1;10;0c' when sent to the client on reconnect.

This adds an additional filter pass when sending the replay buffer,
ensuring no DA1 responses reach the client regardless of when they
were captured.
This commit is contained in:
GitHub Copilot
2026-01-29 19:13:40 +00:00
parent 3c4e62b572
commit d5343117d3
9 changed files with 48 additions and 33 deletions
+1
View File
@@ -40,6 +40,7 @@ class TestCLI:
def test_cli_runs_default_shell(self, monkeypatch):
import os
calls: dict[str, object] = {}
class FakeServer:
-2
View File
@@ -7,7 +7,6 @@ from webterm import cli
def test_cli_landing_manifest_runs(monkeypatch, tmp_path: Path):
manifest = tmp_path / "landing.yaml"
manifest.write_text(
"""
@@ -40,7 +39,6 @@ def test_cli_landing_manifest_runs(monkeypatch, tmp_path: Path):
def test_cli_compose_manifest_runs(monkeypatch, tmp_path: Path):
manifest = tmp_path / "compose.yaml"
manifest.write_text(
"""
+5 -5
View File
@@ -172,10 +172,10 @@ class TestDockerStatsCollector:
"""Services can be added dynamically after start."""
collector = DockerStatsCollector("/nonexistent")
collector._service_names = ["svc1"]
collector.add_service("svc2")
assert "svc2" in collector._service_names
# Adding same service again is a no-op
collector.add_service("svc2")
assert collector._service_names.count("svc2") == 1
@@ -183,17 +183,17 @@ class TestDockerStatsCollector:
def test_remove_service_dynamic(self):
"""Services can be removed dynamically."""
from collections import deque
collector = DockerStatsCollector("/nonexistent")
collector._service_names = ["svc1", "svc2"]
collector._cpu_history["svc1"] = deque([10.0, 20.0])
collector._prev_cpu["svc1"] = (100, 200)
collector.remove_service("svc1")
assert "svc1" not in collector._service_names
assert "svc1" not in collector._cpu_history
assert "svc1" not in collector._prev_cpu
# Removing non-existent service is safe
collector.remove_service("nonexistent") # Should not raise
@@ -16,6 +16,7 @@ from webterm.types import RouteKey, SessionID
if TYPE_CHECKING:
from collections.abc import AsyncIterator
async def _make_client(server: LocalServer) -> TestClient:
app = web.Application()
app.add_routes(server._build_routes())
+1
View File
@@ -215,6 +215,7 @@ class TestSessionManager:
assert result is not None
assert isinstance(result, DockerExecSession)
class TestSessionManagerRoutes:
"""Tests for SessionManager route handling."""
+4 -12
View File
@@ -168,17 +168,11 @@ class TestTerminalSession:
session = TerminalSession(mock_poller, "test-session", command)
with (
patch(
"webterm.terminal_session.pty.fork", return_value=(pty.CHILD, 123)
) as mock_fork,
patch("webterm.terminal_session.pty.fork", return_value=(pty.CHILD, 123)) as mock_fork,
patch("webterm.terminal_session.version", return_value="0.0.0"),
patch("webterm.terminal_session.shlex.split", wraps=shlex.split) as mock_split,
patch(
"webterm.terminal_session.os.execvp", side_effect=OSError()
) as mock_execvp,
patch(
"webterm.terminal_session.os._exit", side_effect=SystemExit(1)
) as mock_exit,
patch("webterm.terminal_session.os.execvp", side_effect=OSError()) as mock_execvp,
patch("webterm.terminal_session.os._exit", side_effect=SystemExit(1)) as mock_exit,
pytest.raises(SystemExit),
):
await session.open()
@@ -209,9 +203,7 @@ class TestTerminalSession:
with (
patch("webterm.terminal_session.pty.fork", return_value=(pty.CHILD, 123)),
patch("webterm.terminal_session.shlex.split", side_effect=ValueError("bad")),
patch(
"webterm.terminal_session.os._exit", side_effect=SystemExit(1)
) as mock_exit,
patch("webterm.terminal_session.os._exit", side_effect=SystemExit(1)) as mock_exit,
pytest.raises(SystemExit),
):
await session.open()