test_runner: convert to uint during deserialization

Signed-off-by: Aviv Keller <me@aviv.sh>
PR-URL: https://github.com/nodejs/node/pull/64706
Reviewed-By: Moshe Atlow <moshe@atlow.co.il>
Reviewed-By: Chemi Atlow <chemi@atlow.co.il>
This commit is contained in:
Aviv Keller authored and GitHub committed 2026-07-26 05:17:40 +00:00
1 parent 893602cbf6
commit 1ba3ce45bf
2 files changed
+11 -2

No files matched your search

+2 -2
View File
@@ -466,12 +466,12 @@ class FileTest extends Test {
while (bufferHead?.length >= kSerializedSizeHeader) {
// We call `readUInt32BE` manually here, because this is faster than first converting
// it to a buffer and using `readUInt32BE` on that.
const fullMessageSize = (
const fullMessageSize = ((
bufferHead[kV8HeaderLength] << 24 |
bufferHead[kV8HeaderLength + 1] << 16 |
bufferHead[kV8HeaderLength + 2] << 8 |
bufferHead[kV8HeaderLength + 3]
) + kSerializedSizeHeader;
) >>> 0) + kSerializedSizeHeader;
if (this.#rawBufferSize < fullMessageSize) break;
@@ -30,12 +30,15 @@ defaultSerializer.writeHeader();
const headerLength = defaultSerializer.releaseBuffer().length;
const headerOnly = Buffer.from([0xff, 0x0f]);
const oversizedLengthHeader = Buffer.from([0xff, 0x0f, 0x7f, 0xff, 0xff, 0xff]);
const unsignedOversizedLengthHeader = Buffer.from([0xff, 0x0f, 0x80, 0x00, 0x00, 0x00]);
const truncatedLengthHeader = Buffer.from([0xff, 0x0f, 0x00, 0x01, 0x00, 0x00]);
// Expected stdout for oversizedLengthHeader: first byte is emitted via
// String.fromCharCode (byte-by-byte fallback in #drainRawBuffer), remaining
// bytes go through the nonSerialized UTF-8 decode path in #processRawBuffer.
const oversizedLengthStdout = String.fromCharCode(oversizedLengthHeader[0]) +
Buffer.from(oversizedLengthHeader.subarray(1)).toString('utf-8');
const unsignedOversizedLengthStdout = String.fromCharCode(unsignedOversizedLengthHeader[0]) +
Buffer.from(unsignedOversizedLengthHeader.subarray(1)).toString('utf-8');
function collectStdout(reported) {
return reported
@@ -112,6 +115,12 @@ describe('v8 deserializer', common.mustCall(() => {
assert.strictEqual(collectStdout(reported), oversizedLengthStdout);
});
it('should read an oversized length as an unsigned integer', async () => {
const reported = await collectReported([unsignedOversizedLengthHeader]);
assert(reported.every((event) => event.type === 'test:stdout'));
assert.strictEqual(collectStdout(reported), unsignedOversizedLengthStdout);
});
it('should flush incomplete v8 frame as stdout and keep prior valid data', async () => {
// A valid non-serialized message followed by bytes that look like
// a v8 header with a truncated/oversized length.