// mcp-live-inspect-stdout-cap.test.mjs — #53 (v7.8.3): a hostile MCP stdio // server emitting a giant newline-less stdout line must not buffer unbounded // memory or crash the inspector. The session must abort with a cap error. // Zero external dependencies: node:test + node:assert only. import { describe, it } from 'node:test'; import assert from 'node:assert/strict'; import { inspectServer } from '../../scanners/mcp-live-inspect.mjs'; describe('inspectServer — stdout line byte cap (v7.8.3 #53)', () => { it('aborts on a giant newline-less stdout chunk instead of buffering unbounded', { timeout: 30_000 }, async () => { // Child writes ~10MB with no newline, then stays alive so stdout does // not close. Without a cap the inspector buffers everything and only // fails via the generic RPC timeout. const script = [ 'const b = Buffer.alloc(65536, 120);', 'for (let i = 0; i < 160; i++) process.stdout.write(b);', 'setInterval(() => {}, 1000);', ].join(' '); const descriptor = { name: 'hostile-flood', command: process.execPath, args: ['-e', script], env: {}, }; const result = await inspectServer(descriptor, 20_000); assert.ok(result, 'expected a result object'); assert.ok(result.error, `expected an error result, got: ${JSON.stringify(result).slice(0, 200)}`); assert.match( result.error, /stdout line exceeded/, `expected stdout cap error (not a generic timeout), got: ${result.error}`, ); }); });