diff --git a/src/node_ffi.cc b/src/node_ffi.cc index 732657a368ef..43bd090de7fe 100644 --- a/src/node_ffi.cc +++ b/src/node_ffi.cc @@ -294,10 +294,13 @@ MaybeLocal DynamicLibrary::CreateFunction( bool has_ptr_args = use_sb && SignatureHasPointerArgs(*fn); // Signatures that need JS-side conversion or validation use a wrapper, as // do all fast signatures on platforms without a native library guard. + // Pointer arguments need the wrapper's range check because V8 truncates + // BigInts passed to Fast API uint64 parameters. bool needs_fast_argument_wrapper = - use_fast_api && (SignatureNeedsRawPointerConversions(*fn) || - SignatureNeedsFastIntegerValidation(*fn) || - !info->fast_metadata->guards_library); + use_fast_api && + (SignatureNeedsRawPointerConversions(*fn) || + SignatureNeedsFastIntegerValidation(*fn) || + SignatureHasPointerArgs(*fn) || !info->fast_metadata->guards_library); // A single pointer-like parameter can get a separate Buffer-aware Fast API // entrypoint so Buffer calls avoid JS pointer extraction. bool needs_fast_buffer_invoke = diff --git a/test/ffi/test-ffi-fast-integer-validation.js b/test/ffi/test-ffi-fast-integer-validation.js index e6bedfab967c..e2994c895233 100644 --- a/test/ffi/test-ffi-fast-integer-validation.js +++ b/test/ffi/test-ffi-fast-integer-validation.js @@ -83,15 +83,23 @@ test('fast FFI validates pointer BigInt ranges', () => { arguments: [type, 'u64'], return: 'u64', }); + // Only pointer-like arguments, so no integer type forces the wrapper. + const stringConcat = lib.getFunction('string_concat', { + arguments: [type, type], + return: 'pointer', + }); function callSingle(value) { return identityPointer(value); } function callMultiple(value) { return sumBuffer(value, 0n); } + function callPointers(value) { return stringConcat(value, 0n); } + optimize(callSingle, 0n); optimize(callMultiple, 0n); + optimize(callPointers, 0n); const expect = { code: 'ERR_INVALID_ARG_VALUE' }; - for (const call of [callSingle, callMultiple]) { + for (const call of [callSingle, callMultiple, callPointers]) { assert.throws(() => call(-1n), expect); assert.throws(() => call((2n ** 64n) + 5n), expect); }