Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions lib/internal/test_runner/runner.js
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,25 @@ class FileTest extends Test {
}
#drainRawBuffer() {
while (this.#rawBuffer.length > 0) {
const sizeBefore = this.#rawBufferSize;
const lengthBefore = this.#rawBuffer.length;
this.#processRawBuffer();
if (this.#rawBufferSize === sizeBefore && this.#rawBuffer.length === lengthBefore) {
// The head matches the v8 serializer header but its declared payload
// size exceeds the buffered data and no more data will arrive, so
// flush the leftover bytes as stdout instead of looping forever.
const remaining = this.#rawBuffer.length === 1 ?
this.#rawBuffer[0] :
Buffer.concat(this.#rawBuffer, this.#rawBufferSize);
this.addToReport({
__proto__: null,
type: 'test:stdout',
data: { __proto__: null, file: this.name, message: remaining.toString('utf-8') },
});
this.#rawBuffer = [];
this.#rawBufferSize = 0;
break;
}
}
}
#processRawBuffer() {
Expand Down
11 changes: 11 additions & 0 deletions test/parallel/test-runner-v8-deserializer.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,17 @@ describe('v8 deserializer', common.mustCall(() => {
]);
});

it('should not loop forever on v8 header followed by an oversized length', async () => {
// Refs: https://github.com/nodejs/node/issues/62693
// FF 0F is the v8 serializer header; the following four bytes encode a
// big-endian uint32 payload size that exceeds the buffer.
const malformed = Buffer.from([0xff, 0x0f, 0x7f, 0xff, 0xff, 0xff]);
const reported = await collectReported([malformed]);
assert.deepStrictEqual(reported, [
{ data: { __proto__: null, file: 'filetest', message: malformed.toString('utf-8') }, type: 'test:stdout' },
]);
});

const headerPosition = headerLength * 2 + 4;
for (let i = 0; i < headerPosition + 5; i++) {
const message = `should deserialize a serialized message split into two chunks {...${i},${i + 1}...}`;
Expand Down
Loading