Merge pull request #1899 from codeflash-ai/cf-fix-v8-serializer-cross-context

fix: use cross-context type detection in V8 serializer self-test
This commit is contained in:
Sarthak Agarwal 2026-03-26 23:52:17 +05:30 committed by GitHub
commit 41f64e9459
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -38,16 +38,18 @@ try {
// Verify serialize/deserialize are available // Verify serialize/deserialize are available
if (typeof v8Module.serialize === 'function' && typeof v8Module.deserialize === 'function') { if (typeof v8Module.serialize === 'function' && typeof v8Module.deserialize === 'function') {
// Perform a self-test to verify V8 serialization works correctly // Perform a self-test to verify V8 serialization works correctly
// This catches cases like Jest's VM context where V8 serialization // Use Object.prototype.toString for cross-VM-context detection instead of
// produces data that deserializes incorrectly (Maps become plain objects) // instanceof, which fails in Jest's sandboxed VM where the Map class from
// v8.deserialize differs from the test environment's Map class.
const testMap = new Map([['__test__', 1]]); const testMap = new Map([['__test__', 1]]);
const testBuffer = v8Module.serialize(testMap); const testBuffer = v8Module.serialize(testMap);
const testRestored = v8Module.deserialize(testBuffer); const testRestored = v8Module.deserialize(testBuffer);
if (testRestored instanceof Map && testRestored.get('__test__') === 1) { if (Object.prototype.toString.call(testRestored) === '[object Map]' &&
testRestored.get('__test__') === 1) {
useV8 = true; useV8 = true;
} else { } else {
// V8 serialization is broken in this environment (e.g., Jest) // V8 serialization is truly broken in this environment
useV8 = false; useV8 = false;
} }
} }
@ -157,9 +159,11 @@ function wrapForV8(value, seen = new WeakMap()) {
} }
// V8 handles these natively // V8 handles these natively
if (value instanceof Date || value instanceof RegExp || value instanceof Error || // Use Object.prototype.toString for cross-VM-context detection (Jest sandbox)
value instanceof Map || value instanceof Set || const tag = Object.prototype.toString.call(value);
ArrayBuffer.isView(value) || value instanceof ArrayBuffer) { if (tag === '[object Date]' || tag === '[object RegExp]' || tag === '[object Error]' ||
tag === '[object Map]' || tag === '[object Set]' ||
ArrayBuffer.isView(value) || tag === '[object ArrayBuffer]') {
return value; return value;
} }
@ -219,9 +223,11 @@ function unwrapFromV8(value, seen = new WeakMap()) {
} }
// V8 restores these natively // V8 restores these natively
if (value instanceof Date || value instanceof RegExp || value instanceof Error || // Use Object.prototype.toString for cross-VM-context detection
value instanceof Map || value instanceof Set || const tag = Object.prototype.toString.call(value);
ArrayBuffer.isView(value) || value instanceof ArrayBuffer) { if (tag === '[object Date]' || tag === '[object RegExp]' || tag === '[object Error]' ||
tag === '[object Map]' || tag === '[object Set]' ||
ArrayBuffer.isView(value) || tag === '[object ArrayBuffer]') {
return value; return value;
} }