mirror of
https://github.com/QwenLM/qwen-code.git
synced 2026-05-04 22:51:08 +00:00
fix(cli): prevent terminal response leakage on high-latency SSH
When SSHing into a VM with network latency, terminal responses to startup queries (kitty protocol detection) can arrive after the 200ms timeout expires. The original code immediately restored raw mode, causing late responses to leak through as visible text. This fix adds two layers of defense: 1. Drain handler in kittyProtocolDetector: Adds a 100ms window after timeout to silently consume late-arriving responses 2. Regex filter in KeypressContext: Catches any terminal response patterns that make it past the detection phase, regardless of timing Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
This commit is contained in:
parent
070ec5b43e
commit
d6f5d9997f
2 changed files with 23 additions and 5 deletions
|
|
@ -540,7 +540,16 @@ export function KeypressProvider({
|
|||
}
|
||||
};
|
||||
|
||||
// Matches terminal query responses (DA1, DA2, Kitty protocol query)
|
||||
// that may arrive late from startup detection in kittyProtocolDetector.
|
||||
// These are never valid user input.
|
||||
// eslint-disable-next-line no-control-regex
|
||||
const TERMINAL_RESPONSE_RE = /^\x1b\[[?>][\d;]*[uc]$/;
|
||||
|
||||
const handleKeypress = async (_: unknown, key: Key) => {
|
||||
if (TERMINAL_RESPONSE_RE.test(key.sequence)) {
|
||||
return;
|
||||
}
|
||||
if (key.sequence === FOCUS_IN || key.sequence === FOCUS_OUT) {
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,11 +37,20 @@ export async function detectAndEnableKittyProtocol(): Promise<boolean> {
|
|||
const onTimeout = () => {
|
||||
timeoutId = undefined;
|
||||
process.stdin.removeListener('data', handleData);
|
||||
if (!originalRawMode) {
|
||||
process.stdin.setRawMode(false);
|
||||
}
|
||||
detectionComplete = true;
|
||||
resolve(false);
|
||||
|
||||
// Keep a drain handler briefly to consume any late-arriving terminal
|
||||
// responses that would otherwise leak into the application input.
|
||||
const drainHandler = () => {};
|
||||
process.stdin.on('data', drainHandler);
|
||||
|
||||
setTimeout(() => {
|
||||
process.stdin.removeListener('data', drainHandler);
|
||||
if (!originalRawMode) {
|
||||
process.stdin.setRawMode(false);
|
||||
}
|
||||
detectionComplete = true;
|
||||
resolve(false);
|
||||
}, 100);
|
||||
};
|
||||
|
||||
const handleData = (data: Buffer) => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue