Skip to content

Commit 0aa1c1b

Browse files
committed
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>
1 parent adcd028 commit 0aa1c1b

1 file changed

Lines changed: 32 additions & 27 deletions

File tree

‎test/parallel/test-runner-v8-deserializer.mjs‎

Lines changed: 32 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -27,49 +27,54 @@ const reportedDiagnosticEvent = {
2727
const chunks = await toArray(serializer([diagnosticEvent]));
2828
const defaultSerializer = new DefaultSerializer();
2929
defaultSerializer.writeHeader();
30-
const headerLength = defaultSerializer.releaseBuffer().length;
31-
const headerOnly = Buffer.from([0xff, 0x0f]);
32-
const oversizedLengthHeader = Buffer.from([0xff, 0x0f, 0x7f, 0xff, 0xff, 0xff]);
33-
const unsignedOversizedLengthHeader = Buffer.from([0xff, 0x0f, 0x80, 0x00, 0x00, 0x00]);
34-
const truncatedLengthHeader = Buffer.from([0xff, 0x0f, 0x00, 0x01, 0x00, 0x00]);
30+
const headerOnly = Buffer.from(defaultSerializer.releaseBuffer());
31+
const headerLength = headerOnly.length;
32+
const oversizedLengthHeader = Buffer.concat([headerOnly, Buffer.from([0x7f, 0xff, 0xff, 0xff])]);
33+
const unsignedOversizedLengthHeader = Buffer.concat([headerOnly, Buffer.from([0x80, 0x00, 0x00, 0x00])]);
34+
const truncatedLengthHeader = Buffer.concat([headerOnly, Buffer.from([0x00, 0x01, 0x00, 0x00])]);
3535
// Expected stdout for oversizedLengthHeader: first byte is emitted via
3636
// String.fromCharCode (byte-by-byte fallback in #drainRawBuffer), remaining
3737
// bytes go through the nonSerialized UTF-8 decode path in #processRawBuffer.
3838
const oversizedLengthStdout = String.fromCharCode(oversizedLengthHeader[0]) +
3939
Buffer.from(oversizedLengthHeader.subarray(1)).toString('utf-8');
4040
const unsignedOversizedLengthStdout = String.fromCharCode(unsignedOversizedLengthHeader[0]) +
4141
Buffer.from(unsignedOversizedLengthHeader.subarray(1)).toString('utf-8');
42-
// FF 0F followed by a small, plausible size (8) and 8 payload bytes. Unlike the
42+
function payloadSize(size) {
43+
const buffer = Buffer.alloc(4);
44+
buffer.writeUInt32BE(size);
45+
return buffer;
46+
}
47+
// The v8 header followed by a small, plausible size (8) and 8 payload bytes. Unlike the
4348
// oversized headers above, this passes the size check, but its payload does not
4449
// begin with the inner v8 header a real frame carries, so it is treated as
4550
// stdout instead of reaching the deserializer.
4651
// Regression fixture for https://github.com/nodejs/node/issues/66164
47-
const plausibleSizeFalseHeader = Buffer.from([
48-
0xff, 0x0f, // V8 serializer header magic
49-
0x00, 0x00, 0x00, 0x08, // Payload size of 8 bytes
50-
0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, // "ABCDEFGH", not a real payload
52+
const plausibleSizeFalseHeader = Buffer.concat([
53+
headerOnly,
54+
payloadSize(8),
55+
Buffer.from('ABCDEFGH'), // Not a real payload
5156
]);
5257
const plausibleSizeFalseHeaderStdout = String.fromCharCode(plausibleSizeFalseHeader[0]) +
5358
Buffer.from(plausibleSizeFalseHeader.subarray(1)).toString('utf-8');
54-
// FF 0F, a valid size, then the inner v8 header a real frame repeats, followed
59+
// The v8 header, a valid size, then the inner v8 header a real frame repeats, followed
5560
// by a byte that is not a valid serialized value. This passes the inner header
5661
// check and reaches the deserializer, which throws. This is what a genuine
5762
// report-protocol regression looks like, so the parser must let the error
5863
// surface instead of hiding it as stdout.
59-
const headeredCorruptFrame = Buffer.from([
60-
0xff, 0x0f, // Outer v8 serializer header magic
61-
0x00, 0x00, 0x00, 0x03, // Payload size of 3 bytes
62-
0xff, 0x0f, // Inner v8 header that a real frame repeats
63-
0xee, // Not a valid serialized value
64+
const headeredCorruptFrame = Buffer.concat([
65+
headerOnly,
66+
payloadSize(headerLength + 1),
67+
headerOnly,
68+
Buffer.from([0xee]), // Not a valid serialized value
6469
]);
65-
// FF 0F with a declared size of 1, then more header bytes. The payload is
70+
// The v8 header with a declared size of 1, then more header bytes. The payload is
6671
// shorter than the inner v8 header a real frame carries, so it can never be a
6772
// real frame. The length guard must reject it as stdout without reaching the
6873
// deserializer.
69-
const shortPayloadFalseHeader = Buffer.from([
70-
0xff, 0x0f, // Outer v8 serializer header magic
71-
0x00, 0x00, 0x00, 0x01, // Payload size of 1 byte, too short for a header
72-
0xff, 0x0f, // Trailing bytes that also look like a header
74+
const shortPayloadFalseHeader = Buffer.concat([
75+
headerOnly,
76+
payloadSize(1),
77+
headerOnly, // Trailing bytes that also look like a header
7378
]);
7479

7580
function collectStdout(reported) {
@@ -144,10 +149,10 @@ describe('v8 deserializer', common.mustCall(() => {
144149

145150
it('should not hang when buffer starts with v8Header followed by oversized length', async () => {
146151
// Regression test for https://github.com/nodejs/node/issues/62693
147-
// FF 0F is the v8 serializer header; the next 4 bytes are read as a
148-
// big-endian message size. 0x7FFFFFFF far exceeds any actual buffer
149-
// size, causing #processRawBuffer to make no progress and
150-
// #drainRawBuffer to loop forever without the no-progress guard.
152+
// The v8 serializer header is followed by 4 bytes read as a big-endian
153+
// message size. 0x7FFFFFFF far exceeds any actual buffer size, causing
154+
// #processRawBuffer to make no progress and #drainRawBuffer to loop
155+
// forever without the no-progress guard.
151156
const reported = await collectReported([oversizedLengthHeader]);
152157
assert.partialDeepStrictEqual(
153158
reported,
@@ -173,14 +178,14 @@ describe('v8 deserializer', common.mustCall(() => {
173178
});
174179

175180
it('should flush v8Header-only bytes as stdout when stream ends', async () => {
176-
// Just the two-byte v8 header with no size field at all.
181+
// Just the v8 header bytes with no size field at all.
177182
const reported = await collectReported([headerOnly]);
178183
assert(reported.every((event) => event.type === 'test:stdout'));
179184
assert.strictEqual(collectStdout(reported), headerOnly.toString('latin1'));
180185
});
181186

182187
it('should resync and parse valid messages after false v8 header', async () => {
183-
// A false v8 header (FF 0F + oversized length) followed by a
188+
// A false v8 header (header bytes + oversized length) followed by a
184189
// legitimate serialized message. The parser must skip the corrupt
185190
// bytes and still deserialize the real message.
186191
const reported = await collectReported([

0 commit comments

Comments
 (0)