diff --git a/packages/core/src/services/shellExecutionService.test.ts b/packages/core/src/services/shellExecutionService.test.ts index 749150361f..b2ec495d09 100644 --- a/packages/core/src/services/shellExecutionService.test.ts +++ b/packages/core/src/services/shellExecutionService.test.ts @@ -1610,6 +1610,22 @@ describe('ShellExecutionService child_process fallback', () => { 'exit', ]); }); + + it('should correctly measure sniffedBytes with >20 small chunks to prevent OOM (regression #22170)', async () => { + mockIsBinary.mockReturnValue(false); + + await simulateExecution('cat lots_of_chunks', (cp) => { + for (let i = 0; i < 25; i++) { + cp.stdout?.emit('data', Buffer.alloc(10, 'a')); + } + cp.emit('exit', 0, null); + cp.emit('close', 0, null); + }); + + const lastCallBuffer = + mockIsBinary.mock.calls[mockIsBinary.mock.calls.length - 1][0]; + expect(lastCallBuffer.length).toBe(250); + }); }); describe('Platform-Specific Behavior', () => { diff --git a/packages/core/src/services/shellExecutionService.ts b/packages/core/src/services/shellExecutionService.ts index 607d84ef8d..1c126dab6f 100644 --- a/packages/core/src/services/shellExecutionService.ts +++ b/packages/core/src/services/shellExecutionService.ts @@ -630,7 +630,7 @@ export class ShellExecutionService { } if (isStreamingRawContent && sniffedBytes < MAX_SNIFF_SIZE) { - const sniffBuffer = Buffer.concat(state.sniffChunks.slice(0, 20)); + const sniffBuffer = Buffer.concat(state.sniffChunks); sniffedBytes = sniffBuffer.length; if (isBinary(sniffBuffer)) { @@ -1094,7 +1094,7 @@ export class ShellExecutionService { } if (isStreamingRawContent && sniffedBytes < MAX_SNIFF_SIZE) { - const sniffBuffer = Buffer.concat(sniffChunks.slice(0, 20)); + const sniffBuffer = Buffer.concat(sniffChunks); sniffedBytes = sniffBuffer.length; if (isBinary(sniffBuffer)) {