Commit cfb6aa17494 for nodejs
commit cfb6aa17494167f2358fb54890c99d76c2c25beb
Author: Joyee Cheung <joyeec9h3@gmail.com>
Date: Fri Oct 2 18:56:58 2026 +0200
test: do not hardcode V8 serialization header
The header changes when V8 is updated. Do not hardcode it to
avoid breaking V8 updates. The update should only surface in
test/parallel/test-v8-serdes.js
Signed-off-by: Joyee Cheung <joyeec9h3@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/66442
Refs: https://github.com/nodejs/node/pull/65161
Reviewed-By: Shelley Vohr <shelley.vohr@gmail.com>
Reviewed-By: Richard Lau <richard.lau@ibm.com>
diff --git a/test/parallel/test-runner-v8-deserializer.mjs b/test/parallel/test-runner-v8-deserializer.mjs
index 38a7feae059..f376ca6edb8 100644
--- a/test/parallel/test-runner-v8-deserializer.mjs
+++ b/test/parallel/test-runner-v8-deserializer.mjs
@@ -27,11 +27,11 @@ const reportedDiagnosticEvent = {
const chunks = await toArray(serializer([diagnosticEvent]));
const defaultSerializer = new DefaultSerializer();
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]);
+const headerOnly = Buffer.from(defaultSerializer.releaseBuffer());
+const headerLength = headerOnly.length;
+const oversizedLengthHeader = Buffer.concat([headerOnly, Buffer.from([0x7f, 0xff, 0xff, 0xff])]);
+const unsignedOversizedLengthHeader = Buffer.concat([headerOnly, Buffer.from([0x80, 0x00, 0x00, 0x00])]);
+const truncatedLengthHeader = Buffer.concat([headerOnly, Buffer.from([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.
@@ -39,37 +39,42 @@ 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');
-// FF 0F followed by a small, plausible size (8) and 8 payload bytes. Unlike the
+function payloadSize(size) {
+ const buffer = Buffer.alloc(4);
+ buffer.writeUInt32BE(size);
+ return buffer;
+}
+// The v8 header followed by a small, plausible size (8) and 8 payload bytes. Unlike the
// oversized headers above, this passes the size check, but its payload does not
// begin with the inner v8 header a real frame carries, so it is treated as
// stdout instead of reaching the deserializer.
// Regression fixture for https://github.com/nodejs/node/issues/66164
-const plausibleSizeFalseHeader = Buffer.from([
- 0xff, 0x0f, // V8 serializer header magic
- 0x00, 0x00, 0x00, 0x08, // Payload size of 8 bytes
- 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, // "ABCDEFGH", not a real payload
+const plausibleSizeFalseHeader = Buffer.concat([
+ headerOnly,
+ payloadSize(8),
+ Buffer.from('ABCDEFGH'), // Not a real payload
]);
const plausibleSizeFalseHeaderStdout = String.fromCharCode(plausibleSizeFalseHeader[0]) +
Buffer.from(plausibleSizeFalseHeader.subarray(1)).toString('utf-8');
-// FF 0F, a valid size, then the inner v8 header a real frame repeats, followed
+// The v8 header, a valid size, then the inner v8 header a real frame repeats, followed
// by a byte that is not a valid serialized value. This passes the inner header
// check and reaches the deserializer, which throws. This is what a genuine
// report-protocol regression looks like, so the parser must let the error
// surface instead of hiding it as stdout.
-const headeredCorruptFrame = Buffer.from([
- 0xff, 0x0f, // Outer v8 serializer header magic
- 0x00, 0x00, 0x00, 0x03, // Payload size of 3 bytes
- 0xff, 0x0f, // Inner v8 header that a real frame repeats
- 0xee, // Not a valid serialized value
+const headeredCorruptFrame = Buffer.concat([
+ headerOnly,
+ payloadSize(headerLength + 1),
+ headerOnly,
+ Buffer.from([0xee]), // Not a valid serialized value
]);
-// FF 0F with a declared size of 1, then more header bytes. The payload is
+// The v8 header with a declared size of 1, then more header bytes. The payload is
// shorter than the inner v8 header a real frame carries, so it can never be a
// real frame. The length guard must reject it as stdout without reaching the
// deserializer.
-const shortPayloadFalseHeader = Buffer.from([
- 0xff, 0x0f, // Outer v8 serializer header magic
- 0x00, 0x00, 0x00, 0x01, // Payload size of 1 byte, too short for a header
- 0xff, 0x0f, // Trailing bytes that also look like a header
+const shortPayloadFalseHeader = Buffer.concat([
+ headerOnly,
+ payloadSize(1),
+ headerOnly, // Trailing bytes that also look like a header
]);
function collectStdout(reported) {
@@ -144,10 +149,10 @@ describe('v8 deserializer', common.mustCall(() => {
it('should not hang when buffer starts with v8Header followed by oversized length', async () => {
// Regression test for https://github.com/nodejs/node/issues/62693
- // FF 0F is the v8 serializer header; the next 4 bytes are read as a
- // big-endian message size. 0x7FFFFFFF far exceeds any actual buffer
- // size, causing #processRawBuffer to make no progress and
- // #drainRawBuffer to loop forever without the no-progress guard.
+ // The v8 serializer header is followed by 4 bytes read as a big-endian
+ // message size. 0x7FFFFFFF far exceeds any actual buffer size, causing
+ // #processRawBuffer to make no progress and #drainRawBuffer to loop
+ // forever without the no-progress guard.
const reported = await collectReported([oversizedLengthHeader]);
assert.partialDeepStrictEqual(
reported,
@@ -173,14 +178,14 @@ describe('v8 deserializer', common.mustCall(() => {
});
it('should flush v8Header-only bytes as stdout when stream ends', async () => {
- // Just the two-byte v8 header with no size field at all.
+ // Just the v8 header bytes with no size field at all.
const reported = await collectReported([headerOnly]);
assert(reported.every((event) => event.type === 'test:stdout'));
assert.strictEqual(collectStdout(reported), headerOnly.toString('latin1'));
});
it('should resync and parse valid messages after false v8 header', async () => {
- // A false v8 header (FF 0F + oversized length) followed by a
+ // A false v8 header (header bytes + oversized length) followed by a
// legitimate serialized message. The parser must skip the corrupt
// bytes and still deserialize the real message.
const reported = await collectReported([