From 7f58bcef179846d169cb5ab5dfcd61e42d13152c Mon Sep 17 00:00:00 2001 From: cmliu Date: Wed, 29 Jul 2026 21:28:41 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=20retainTrailingMark?= =?UTF-8?q?erPrefix=20=E5=87=BD=E6=95=B0=E4=BB=A5=E5=A4=84=E7=90=86?= =?UTF-8?q?=E7=BC=93=E5=86=B2=E5=8C=BA=E4=B8=AD=E7=9A=84=E5=B0=BE=E9=83=A8?= =?UTF-8?q?=E6=A0=87=E8=AE=B0=E5=89=8D=E7=BC=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/backend/process-framing.ts | 7 +++++++ src/backend/session.ts | 7 +++++-- 2 files changed, 12 insertions(+), 2 deletions(-) create mode 100644 src/backend/process-framing.ts diff --git a/src/backend/process-framing.ts b/src/backend/process-framing.ts new file mode 100644 index 0000000..e5e7119 --- /dev/null +++ b/src/backend/process-framing.ts @@ -0,0 +1,7 @@ +export function retainTrailingMarkerPrefix(buffer: string, marker: string): string { + const maxLength = Math.min(buffer.length, Math.max(0, marker.length - 1)); + for (let length = maxLength; length > 0; length--) { + if (buffer.endsWith(marker.slice(0, length))) return buffer.slice(-length); + } + return ''; +} diff --git a/src/backend/session.ts b/src/backend/session.ts index b3c589c..1367684 100644 --- a/src/backend/session.ts +++ b/src/backend/session.ts @@ -47,6 +47,7 @@ import { SFTPHandler } from './sftp-handler'; import { classifyHostKey } from '../ssh/host-key'; import { encodeString, readUint32, toBufferSource } from '../ssh/utils'; import { parseTopSnapshot } from './top-parser'; +import { retainTrailingMarkerPrefix } from './process-framing'; type Cipher = SSHAESGCMCipher | SSHAESCTRCipher; type Phase = 'version' | 'kex' | 'host-confirm' | 'auth' | 'pty' | 'shell' | 'ready' | 'closed'; @@ -851,14 +852,16 @@ export class SSHSession { this.processBuffer += this.processDecoder.decode(data, { stream: true }); if (this.processBuffer.length > PROCESS_MAX_BUFFER_BYTES) { const marker = this.processBuffer.lastIndexOf(PROCESS_SNAPSHOT_MARKER); - this.processBuffer = marker >= 0 ? this.processBuffer.slice(marker) : ''; + this.processBuffer = marker >= 0 + ? this.processBuffer.slice(marker) + : retainTrailingMarkerPrefix(this.processBuffer, PROCESS_SNAPSHOT_MARKER); this.sendProcessError('Process snapshot exceeded the buffer limit'); return; } while (true) { const first = this.processBuffer.indexOf(PROCESS_SNAPSHOT_MARKER); if (first < 0) { - if (this.processBuffer.length > PROCESS_SNAPSHOT_MARKER.length) this.processBuffer = ''; + this.processBuffer = retainTrailingMarkerPrefix(this.processBuffer, PROCESS_SNAPSHOT_MARKER); return; } if (first > 0) this.processBuffer = this.processBuffer.slice(first);