From a5ff09c8f054e8df12a4fc84d0533b9476791d68 Mon Sep 17 00:00:00 2001 From: "Kamat, Trivikram" <16024985+trivikr@users.noreply.github.com> Date: Wed, 22 Jul 2026 23:30:33 -0700 Subject: [PATCH] ffi: validate fast i32 argument ranges Add i32 and int32 to Fast API integer validation so optimized calls reject invalid values instead of allowing V8 to truncate them. Signed-off-by: Kamat, Trivikram <16024985+trivikr@users.noreply.github.com> Assisted-by: openai:gpt-5.6-sol --- lib/internal/ffi/fast-api.js | 2 ++ src/ffi/fast.cc | 4 ++-- test/ffi/test-ffi-fast-integer-validation.js | 7 +++++++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/lib/internal/ffi/fast-api.js b/lib/internal/ffi/fast-api.js index 11e8c005dee98c..71aaca962d17c4 100644 --- a/lib/internal/ffi/fast-api.js +++ b/lib/internal/ffi/fast-api.js @@ -51,6 +51,8 @@ const fastIntegerTypeInfo = { int16: { kind: 'number', min: -32768, max: 32767, label: 'an int16' }, u16: { kind: 'number', min: 0, max: 65535, label: 'a uint16' }, uint16: { kind: 'number', min: 0, max: 65535, label: 'a uint16' }, + i32: { kind: 'number', min: -2147483648, max: 2147483647, label: 'an int32' }, + int32: { kind: 'number', min: -2147483648, max: 2147483647, label: 'an int32' }, i64: { kind: 'bigint', min: I64_MIN, max: I64_MAX, label: 'an int64' }, int64: { kind: 'bigint', min: I64_MIN, max: I64_MAX, label: 'an int64' }, u64: { kind: 'bigint', min: 0n, max: U64_MAX, label: 'a uint64' }, diff --git a/src/ffi/fast.cc b/src/ffi/fast.cc index 8c4420761fec1d..ce8f0e57b2d1cd 100644 --- a/src/ffi/fast.cc +++ b/src/ffi/fast.cc @@ -164,8 +164,8 @@ bool SignatureNeedsFastIntegerValidation(const FFIFunction& fn) { for (const std::string& name : fn.arg_type_names) { if (name == "bool" || name == "char" || name == "i8" || name == "int8" || name == "u8" || name == "uint8" || name == "i16" || name == "int16" || - name == "u16" || name == "uint16" || name == "i64" || name == "int64" || - name == "u64" || name == "uint64") { + name == "u16" || name == "uint16" || name == "i32" || name == "int32" || + name == "i64" || name == "int64" || name == "u64" || name == "uint64") { return true; } } diff --git a/test/ffi/test-ffi-fast-integer-validation.js b/test/ffi/test-ffi-fast-integer-validation.js index 49fd1364948c35..d75cec0cf0eac6 100644 --- a/test/ffi/test-ffi-fast-integer-validation.js +++ b/test/ffi/test-ffi-fast-integer-validation.js @@ -28,6 +28,8 @@ test('fast FFI validates integer argument ranges', () => { function callU16(value) { return functions.add_u16(value, 0); } + function callI32(value) { return functions.add_i32(value, 0); } + function callI64(value) { return functions.add_i64(value, 0n); } function callU64(value) { return functions.add_u64(value, 0n); } @@ -37,6 +39,7 @@ test('fast FFI validates integer argument ranges', () => { [callU8, 0], [callI16, 0], [callU16, 0], + [callI32, 0], [callI64, 0n], [callU64, 0n], ]) { @@ -48,6 +51,10 @@ test('fast FFI validates integer argument ranges', () => { assert.throws(() => callU8(256), expect); assert.throws(() => callI16(32768), expect); assert.throws(() => callU16(65536), expect); + assert.throws(() => callI32(2147483648), expect); + assert.throws(() => callI32(-2147483649), expect); + assert.throws(() => callI32(1.5), expect); + assert.throws(() => callI32('1'), expect); assert.throws(() => callI64(2n ** 63n), expect); assert.throws(() => callU64(2n ** 64n), expect); } finally {