Skip to content

Commit c8e2a82

Browse files
authored
ffi: validate fast 32-bit integer argument ranges
Add i32, int32, u32, and uint32 to Fast API integer validation so optimized calls reject invalid values instead of allowing V8 to coerce or truncate them. Signed-off-by: Kamat, Trivikram <16024985+trivikr@users.noreply.github.com> Assisted-by: openai:gpt-5.6-sol PR-URL: #64691 Fixes: #64690 Reviewed-By: Aviv Keller <me@aviv.sh> Reviewed-By: Paolo Insogna <paolo@cowtech.it>
1 parent f85fdab commit c8e2a82

3 files changed

Lines changed: 20 additions & 1 deletion

File tree

lib/internal/ffi/fast-api.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@ const fastIntegerTypeInfo = {
4646
int16: { kind: 'number', min: -32768, max: 32767, label: 'an int16' },
4747
u16: { kind: 'number', min: 0, max: 65535, label: 'a uint16' },
4848
uint16: { kind: 'number', min: 0, max: 65535, label: 'a uint16' },
49+
i32: { kind: 'number', min: -2147483648, max: 2147483647, label: 'an int32' },
50+
int32: { kind: 'number', min: -2147483648, max: 2147483647, label: 'an int32' },
51+
u32: { kind: 'number', min: 0, max: 4294967295, label: 'a uint32' },
52+
uint32: { kind: 'number', min: 0, max: 4294967295, label: 'a uint32' },
4953
i64: { kind: 'bigint', min: I64_MIN, max: I64_MAX, label: 'an int64' },
5054
int64: { kind: 'bigint', min: I64_MIN, max: I64_MAX, label: 'an int64' },
5155
u64: { kind: 'bigint', min: 0n, max: U64_MAX, label: 'a uint64' },

src/ffi/fast.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,8 @@ bool SignatureNeedsFastIntegerValidation(const FFIFunction& fn) {
164164
for (const std::string& name : fn.arg_type_names) {
165165
if (name == "bool" || name == "char" || name == "i8" || name == "int8" ||
166166
name == "u8" || name == "uint8" || name == "i16" || name == "int16" ||
167-
name == "u16" || name == "uint16" || name == "i64" || name == "int64" ||
167+
name == "u16" || name == "uint16" || name == "i32" || name == "int32" ||
168+
name == "u32" || name == "uint32" || name == "i64" || name == "int64" ||
168169
name == "u64" || name == "uint64") {
169170
return true;
170171
}

test/ffi/test-ffi-fast-integer-validation.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ test('fast FFI validates integer argument ranges', () => {
2828

2929
function callU16(value) { return functions.add_u16(value, 0); }
3030

31+
function callI32(value) { return functions.add_i32(value, 0); }
32+
33+
function callU32(value) { return functions.add_u32(value, 0); }
34+
3135
function callI64(value) { return functions.add_i64(value, 0n); }
3236

3337
function callU64(value) { return functions.add_u64(value, 0n); }
@@ -37,6 +41,8 @@ test('fast FFI validates integer argument ranges', () => {
3741
[callU8, 0],
3842
[callI16, 0],
3943
[callU16, 0],
44+
[callI32, 0],
45+
[callU32, 0],
4046
[callI64, 0n],
4147
[callU64, 0n],
4248
]) {
@@ -48,6 +54,14 @@ test('fast FFI validates integer argument ranges', () => {
4854
assert.throws(() => callU8(256), expect);
4955
assert.throws(() => callI16(32768), expect);
5056
assert.throws(() => callU16(65536), expect);
57+
assert.throws(() => callI32(2147483648), expect);
58+
assert.throws(() => callI32(-2147483649), expect);
59+
assert.throws(() => callI32(1.5), expect);
60+
assert.throws(() => callI32('1'), expect);
61+
assert.throws(() => callU32(4294967296), expect);
62+
assert.throws(() => callU32(-1), expect);
63+
assert.throws(() => callU32(1.5), expect);
64+
assert.throws(() => callU32('1'), expect);
5165
assert.throws(() => callI64(2n ** 63n), expect);
5266
assert.throws(() => callU64(2n ** 64n), expect);
5367
} finally {

0 commit comments

Comments
 (0)