Commit 67a44165dbc for nodejs

commit 67a44165dbc46b912f1b3b4c0ca3346f9b6a1765
Author: Alexey Karimov <krassx@gmail.com>
Date:   Mon Sep 21 17:37:14 2026 +0500

    node-api: do not crash on module version mismatch

    `node_napi_env__::New()` returns nullptr after throwing when an add-on
    declares a Node-API version this binary does not support, but
    `napi_module_register_by_symbol()` dereferenced the result without
    checking it. Loading such an add-on segfaulted instead of surfacing the
    error the version check had already produced, so `require()` could not
    catch it.

    Reproduced on v20.x, v22.x, v24.x and v26.8.2 with a ten-line add-on
    whose only distinguishing content is a NAPI_VERSION above
    NODE_API_SUPPORTED_VERSION_MAX. `main`, `v22.x-staging` and
    `v24.x-staging` all lack the check.

    The error path had no test coverage: the message text appears in exactly
    one file in the repository, `src/node_api.cc`. A test is added next to
    `test_null_init`, which covers the sibling early return in the same
    function.

    Prepared with assistance from a closed-source coding agent, named in the
    pull request description. The design, review and validation are my own:
    I verified the fix and the test against a local build, including
    removing the four added lines and relinking to confirm the test fails
    without them.

    Refs: https://github.com/nodejs/node/issues/57233
    Signed-off-by: Alexey Karimov <krassx@gmail.com>
    PR-URL: https://github.com/nodejs/node/pull/66019
    Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
    Reviewed-By: James M Snell <jasnell@gmail.com>

diff --git a/src/node_api.cc b/src/node_api.cc
index e0e7cca2a4b..40bdf143a98 100644
--- a/src/node_api.cc
+++ b/src/node_api.cc
@@ -770,6 +770,8 @@ void napi_module_register_by_symbol(v8::Local<v8::Object> exports,
   // Create a new napi_env for this specific module.
   napi_env env =
       node_napi_env__::New(context, module_filename, module_api_version);
+  // `module_api_version` is not supported.
+  if (env == nullptr) return;

   napi_value _exports = nullptr;
   env->CallIntoModule([&](napi_env env) {
diff --git a/test/node-api/test_module_version_mismatch/binding.gyp b/test/node-api/test_module_version_mismatch/binding.gyp
new file mode 100644
index 00000000000..e87600d8fa4
--- /dev/null
+++ b/test/node-api/test_module_version_mismatch/binding.gyp
@@ -0,0 +1,12 @@
+{
+  'targets': [
+    {
+      'target_name': 'test_module_version_mismatch',
+      'sources': [ 'test_module_version_mismatch.c' ],
+      # One below NAPI_VERSION_EXPERIMENTAL, so it is always above
+      # NODE_API_SUPPORTED_VERSION_MAX and never becomes a real version, but is
+      # not the experimental value the version check deliberately allows.
+      'defines': [ 'NAPI_VERSION=2147483646' ]
+    }
+  ]
+}
diff --git a/test/node-api/test_module_version_mismatch/test.js b/test/node-api/test_module_version_mismatch/test.js
new file mode 100644
index 00000000000..1881c69c0e2
--- /dev/null
+++ b/test/node-api/test_module_version_mismatch/test.js
@@ -0,0 +1,10 @@
+'use strict';
+const common = require('../../common');
+const assert = require('assert');
+
+// An add-on that requires a newer Node-API version than this binary supports
+// must be rejected with an error that `require()` can catch, rather than
+// crashing the process.
+assert.throws(
+  () => require(`./build/${common.buildType}/test_module_version_mismatch`),
+  /requires Node-API version 2147483646, but this version of Node\.js only supports version \d+ add-ons\./);
diff --git a/test/node-api/test_module_version_mismatch/test_module_version_mismatch.c b/test/node-api/test_module_version_mismatch/test_module_version_mismatch.c
new file mode 100644
index 00000000000..63027b705b2
--- /dev/null
+++ b/test/node-api/test_module_version_mismatch/test_module_version_mismatch.c
@@ -0,0 +1,7 @@
+#include <node_api.h>
+
+// This add-on declares a Node-API version that no build supports, so loading it
+// must fail with an error -- not a crash.
+NAPI_MODULE_INIT() {
+  return exports;
+}