fix: filter DA2/DA3 terminal responses to prevent '1;10;0c' display in tmux
When entering or refreshing a webterm session running tmux, the text '1;10;0c' was appearing on screen. This was caused by tmux sending a DA2 (Secondary Device Attributes) query (ESC[>c) to detect terminal capabilities. The filtering code only handled DA1 responses (ESC[?...c) but not DA2 (ESC[>...c) or DA3 (ESC[=...c) responses. Updated the regex patterns to match all three variants: - DA1 (Primary): ESC[?...c - already worked - DA2 (Secondary): ESC[>...c - now fixed (tmux uses this) - DA3 (Tertiary): ESC[=...c - added for completeness The fix applies to: - Live terminal output filtering - Replay buffer filtering on reconnect - Partial escape sequence buffering All 342 tests pass with the updated patterns.
This commit is contained in:
@@ -29,14 +29,17 @@ DEFAULT_SCREEN_WIDTH = 132
|
|||||||
DEFAULT_SCREEN_HEIGHT = 45
|
DEFAULT_SCREEN_HEIGHT = 45
|
||||||
|
|
||||||
# Pattern to filter out terminal device attribute responses that cause display issues
|
# Pattern to filter out terminal device attribute responses that cause display issues
|
||||||
# These are responses to queries that shouldn't be displayed as text.
|
# These are responses to DA1/DA2/DA3 queries that shouldn't be displayed as text
|
||||||
# Matches complete DA1/DA2 responses like \x1b[?1;10;0c or \x1b[?64;1;2;...c
|
# Matches complete responses like:
|
||||||
DA_RESPONSE_PATTERN = re.compile(rb"\x1b\[\?[\d;]+c")
|
# \x1b[?1;10;0c (DA1 - Primary Device Attributes)
|
||||||
|
# \x1b[>1;10;0c (DA2 - Secondary Device Attributes, sent by tmux)
|
||||||
|
# \x1b[=1;0c (DA3 - Tertiary Device Attributes)
|
||||||
|
DA_RESPONSE_PATTERN = re.compile(rb"\x1b\[[?>=][\d;]*c")
|
||||||
|
|
||||||
# Pattern to detect partial DA responses at end of data (incomplete escape sequence)
|
# Pattern to detect partial DA responses at end of data (incomplete escape sequence)
|
||||||
# Matches: \x1b, \x1b[, \x1b[?, \x1b[?1, \x1b[?1;, \x1b[?1;10, etc.
|
# Matches: \x1b, \x1b[, \x1b[?, \x1b[>, \x1b[=, \x1b[?1, \x1b[>1;10, etc.
|
||||||
# These need to be held back until more data arrives to see if they complete
|
# These need to be held back until more data arrives to see if they complete
|
||||||
DA_PARTIAL_PATTERN = re.compile(rb"\x1b(?:\[(?:\?[\d;]*)?)?$")
|
DA_PARTIAL_PATTERN = re.compile(rb"\x1b(?:\[(?:[?>=][\d;]*)?)?$")
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
|
|||||||
@@ -27,10 +27,11 @@ from .session_manager import SessionManager
|
|||||||
from .svg_exporter import render_terminal_svg
|
from .svg_exporter import render_terminal_svg
|
||||||
from .types import Meta, RouteKey, SessionID
|
from .types import Meta, RouteKey, SessionID
|
||||||
|
|
||||||
# Pattern to filter terminal device attribute responses (DA1/DA2) from replay buffer.
|
# Pattern to filter terminal device attribute responses (DA1/DA2/DA3) from replay buffer.
|
||||||
# These responses can appear as visible text like "1;10;0c" if split across reads.
|
# These responses can appear as visible text like "1;10;0c" if split across reads.
|
||||||
|
# Matches: \x1b[?...c (DA1), \x1b[>...c (DA2 from tmux), \x1b[=...c (DA3)
|
||||||
# See docker_exec_session.py and terminal_session.py for main filtering.
|
# See docker_exec_session.py and terminal_session.py for main filtering.
|
||||||
DA_RESPONSE_PATTERN = re.compile(rb"\x1b\[\?[\d;]+c")
|
DA_RESPONSE_PATTERN = re.compile(rb"\x1b\[[?>=][\d;]*c")
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from .config import Config
|
from .config import Config
|
||||||
|
|||||||
@@ -33,13 +33,16 @@ DEFAULT_SCREEN_WIDTH = 132
|
|||||||
DEFAULT_SCREEN_HEIGHT = 45
|
DEFAULT_SCREEN_HEIGHT = 45
|
||||||
|
|
||||||
# Pattern to filter out terminal device attribute responses that cause display issues
|
# Pattern to filter out terminal device attribute responses that cause display issues
|
||||||
# These are responses to DA1/DA2 queries that shouldn't be displayed as text
|
# These are responses to DA1/DA2/DA3 queries that shouldn't be displayed as text
|
||||||
# Matches complete responses like \x1b[?1;10;0c or \x1b[?64;1;2;...c
|
# Matches complete responses like:
|
||||||
DA_RESPONSE_PATTERN = re.compile(rb"\x1b\[\?[\d;]+c")
|
# \x1b[?1;10;0c (DA1 - Primary Device Attributes)
|
||||||
|
# \x1b[>1;10;0c (DA2 - Secondary Device Attributes, sent by tmux)
|
||||||
|
# \x1b[=1;0c (DA3 - Tertiary Device Attributes)
|
||||||
|
DA_RESPONSE_PATTERN = re.compile(rb"\x1b\[[?>=][\d;]*c")
|
||||||
|
|
||||||
# Pattern to detect partial DA responses at end of data (incomplete escape sequence)
|
# Pattern to detect partial DA responses at end of data (incomplete escape sequence)
|
||||||
# Matches: \x1b, \x1b[, \x1b[?, \x1b[?1, \x1b[?1;, etc.
|
# Matches: \x1b, \x1b[, \x1b[?, \x1b[>, \x1b[=, \x1b[?1, \x1b[>1;10, etc.
|
||||||
DA_PARTIAL_PATTERN = re.compile(rb"\x1b(?:\[(?:\?[\d;]*)?)?$")
|
DA_PARTIAL_PATTERN = re.compile(rb"\x1b(?:\[(?:[?>=][\d;]*)?)?$")
|
||||||
|
|
||||||
|
|
||||||
class TerminalSession(Session):
|
class TerminalSession(Session):
|
||||||
|
|||||||
Reference in New Issue
Block a user