fix: answer terminal protocol queries on the daemon, never the browser
Browser xterm.js auto-replies to DA1/DA2/DA3 traveled back over the
websocket and arrived at the PTY after the foreground app had exited,
so the response bytes (\x1b[?62;4;9;22c) landed on the shell prompt as
visible garbage. Move all replies to the daemon's headless xterm where
they reach the PTY synchronously, and suppress every query class on
the browser side. The image addon also registers a {final:"c"} handler
inside the post-mount raf, so re-register suppression after addons
load to stay last in xterm's LIFO dispatch.
Replaces the previous printf-injection test with a real foreground
helper that queries DA1 and asserts the reply lands on stdin, plus a
browser table covering DA1/DA2/DA3 + DSR/CPR/DECRQM.
This commit is contained in:
@@ -162,17 +162,24 @@ describe("terminal emulator runtime in a real browser", () => {
|
||||
expect(refreshCalls.at(-1)).toEqual([0, terminal.rows - 1]);
|
||||
});
|
||||
|
||||
it("suppresses non-identity terminal query responses as PTY input", async () => {
|
||||
it.each([
|
||||
{ name: "DA1", bytes: "\x1b[c" },
|
||||
{ name: "DA1-zero", bytes: "\x1b[0c" },
|
||||
{ name: "DA2", bytes: "\x1b[>c" },
|
||||
{ name: "DA3", bytes: "\x1b[=c" },
|
||||
{ name: "DSR-5", bytes: "\x1b[5n" },
|
||||
{ name: "DSR-6", bytes: "\x1b[6n" },
|
||||
{ name: "DSR-?6", bytes: "\x1b[?6n" },
|
||||
{ name: "DECRQM", bytes: "\x1b[1$p" },
|
||||
{ name: "DECRQM-?", bytes: "\x1b[?1$p" },
|
||||
])("does not emit a PTY input reply for $name", async ({ bytes }) => {
|
||||
await page.viewport(900, 600);
|
||||
const mounted = createTerminalHost({ width: 720, height: 360 });
|
||||
|
||||
await waitFor({ predicate: () => mounted.sizes.length > 0 });
|
||||
|
||||
const querySequences = ["\x1b[5n", "\x1b[6n", "\x1b[?6n", "\x1b[1$p", "\x1b[?1$p"];
|
||||
|
||||
for (const sequence of querySequences) {
|
||||
mounted.runtime.write({ text: sequence });
|
||||
}
|
||||
mounted.runtime.write({ text: bytes });
|
||||
await nextFrame();
|
||||
await nextFrame();
|
||||
|
||||
expect(mounted.inputs).toEqual([]);
|
||||
|
||||
Reference in New Issue
Block a user