mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-10-07 16:09:43 +02:00
fix(input): an oversized paste no longer poisons the durable input queue (#484)
A single input over MAX_INPUT_LENGTH (64 KiB) was queued for reliable
delivery, refused by both transports (the WebSocket silently, POST with a
400), and never dropped: the client treated the 400 as transient, so the
frame was re-sent every 2 s forever, blocked every later input for that
session, and came back from localStorage on every reload.
- Client: a paste over the frame limit is split into in-limit frames
(never cutting a surrogate pair) delivered in seq order; over 1 MiB, or
an oversized mux write, it is refused with a toast and never queued.
- Client: the POST drain drops a frame answered 400/413; a WS error ACK
drops it too; frames over the limit persisted by an older build are
pruned on load.
- Server: the WebSocket answers an oversized sequenced frame with
{t:'ia',seq,err:'too_large',max} instead of silence (an older client
reads that as a plain ACK and drops it); the POST schema uses
MAX_INPUT_LENGTH instead of a second 100000 limit.
Verified end to end on an isolated instance: a 110 KB paste reached the
PTY byte-identical over both the WebSocket and the POST path, a poisoned
120 KB persisted frame was pruned on load, and a 2 MB paste showed the
refusal toast with nothing queued.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -282,6 +282,22 @@ describe('ws-routes', () => {
|
||||
}
|
||||
});
|
||||
|
||||
it('refuses an oversized sequenced frame with an error ACK, so the client can drop it', async () => {
|
||||
// Issue #484: a silent return left the frame unACKed, and the client's
|
||||
// durable queue re-sent it every few seconds forever.
|
||||
const ws = await connectWs('/ws/sessions/ws-test-session/terminal');
|
||||
try {
|
||||
const session = ctx._session;
|
||||
const hugeInput = 'y'.repeat(MAX_INPUT_LENGTH + 1);
|
||||
ws.send(JSON.stringify({ t: 'i', d: hugeInput, cid: 'c1', seq: 3 }));
|
||||
|
||||
expect(await nextMessage(ws)).toEqual({ t: 'ia', seq: 3, err: 'too_large', max: MAX_INPUT_LENGTH });
|
||||
expect(session.writeBuffer).not.toContain(hugeInput);
|
||||
} finally {
|
||||
ws.close();
|
||||
}
|
||||
});
|
||||
|
||||
it('ignores malformed JSON messages', async () => {
|
||||
const ws = await connectWs('/ws/sessions/ws-test-session/terminal');
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user