Skip to content

Commit c5f6603

Browse files
committed
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
1 parent e7904d4 commit c5f6603

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
@@ -50,6 +50,10 @@ const fastIntegerTypeInfo = {
5050
int16: { kind: 'number', min: -32768, max: 32767, label: 'an int16' },
5151
u16: { kind: 'number', min: 0, max: 65535, label: 'a uint16' },
5252
uint16: { kind: 'number', min: 0, max: 65535, label: 'a uint16' },
53+
i32: { kind: 'number', min: -2147483648, max: 2147483647, label: 'an int32' },
54+
int32: { kind: 'number', min: -2147483648, max: 2147483647, label: 'an int32' },
55+
u32: { kind: 'number', min: 0, max: 4294967295, label: 'a uint32' },
56+
uint32: { kind: 'number', min: 0, max: 4294967295, label: 'a uint32' },
5357
i64: { kind: 'bigint', min: I64_MIN, max: I64_MAX, label: 'an int64' },
5458
int64: { kind: 'bigint', min: I64_MIN, max: I64_MAX, label: 'an int64' },
5559
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)