Commit 5c1dcf6b1e2 for nodejs

commit 5c1dcf6b1e2fefb3c17cbcea6f9f8042ab8c312b
Author: Trivikram Kamat <trivikr.dev@gmail.com>
Date:   Fri Oct 30 10:11:26 2026 -0700

    ffi: accept -0 for int32 and uint32 arguments

    ToFFIArgument validated int32/uint32 with IsInt32()/IsUint32(), which
    reject -0, while every other integer width and the Fast API and
    SharedBuffer paths accept it. Use the same validators as the 8- and
    16-bit branches so behavior no longer depends on the JIT tier.

    Signed-off-by: Trivikram Kamat <16024985+trivikr@users.noreply.github.com>
    Assisted-by: claude:opus-5.5
    PR-URL: https://github.com/nodejs/node/pull/67035
    Fixes: https://github.com/nodejs/node/issues/67033
    Reviewed-By: Paolo Insogna <paolo@cowtech.it>
    Reviewed-By: Anna Henningsen <anna@addaleax.net>

diff --git a/src/ffi/types.cc b/src/ffi/types.cc
index 5a910e63a3e..971ca8b6adb 100644
--- a/src/ffi/types.cc
+++ b/src/ffi/types.cc
@@ -634,19 +634,22 @@ Maybe<FFIArgumentCategory> ToFFIArgument(Environment* env,

     *static_cast<uint16_t*>(ret) = static_cast<uint16_t>(value);
   } else if (type == &ffi_type_sint32) {
-    if (!arg->IsInt32()) {
+    int64_t value;
+    if (!GetValidatedSignedInt(env, arg, INT32_MIN, INT32_MAX, "int32")
+             .To(&value)) {
       THROW_ERR_INVALID_ARG_VALUE(env, "Argument %u must be an int32", index);
       return {};
     }

-    *static_cast<int32_t*>(ret) = arg->Int32Value(context).FromJust();
+    *static_cast<int32_t*>(ret) = static_cast<int32_t>(value);
   } else if (type == &ffi_type_uint32) {
-    if (!arg->IsUint32()) {
+    uint64_t value;
+    if (!GetValidatedUnsignedInt(env, arg, UINT32_MAX, "uint32").To(&value)) {
       THROW_ERR_INVALID_ARG_VALUE(env, "Argument %u must be a uint32", index);
       return {};
     }

-    *static_cast<uint32_t*>(ret) = arg->Uint32Value(context).FromJust();
+    *static_cast<uint32_t*>(ret) = static_cast<uint32_t>(value);
   } else if (type == &ffi_type_sint64) {
     if (arg->IsBigInt()) {
       bool lossless;
diff --git a/test/ffi/test-ffi-calls.js b/test/ffi/test-ffi-calls.js
index 0dbddb244b7..338a728bd22 100644
--- a/test/ffi/test-ffi-calls.js
+++ b/test/ffi/test-ffi-calls.js
@@ -20,6 +20,8 @@ test('ffi calls support integer arithmetic and char semantics', () => {
     assert.strictEqual(symbols.add_u16(65_530, 10), 4);
     assert.strictEqual(symbols.add_i32(-10, 52), 42);
     assert.strictEqual(symbols.add_u32(0xFFFFFFFF, 1), 0);
+    assert.strictEqual(symbols.add_i32(-0, 1), 1);
+    assert.strictEqual(symbols.add_u32(-0, 1), 1);
     assert.strictEqual(symbols.add_i64(20n, 22n), 42n);
     assert.strictEqual(symbols.add_u64(20n, 22n), 42n);
     assert.strictEqual(symbols.add_i64(20, 22), symbols.add_i64(20n, 22n));