deno
9d13e9d3 - fix(ext/napi): clear error for Windows addons that link against node.exe (#34696)

Commit
48 days ago
fix(ext/napi): clear error for Windows addons that link against node.exe (#34696) ## Problem Loading uWebSockets.js (and similar prebuilt native addons) on **Windows** fails with a cryptic error: ``` error: Uncaught (in promise) Error: This version of uWS.js supports only Node.js LTS versions 16, 18 and 20 ... TypeError: LoadLibraryExW failed ``` The "supports only Node.js LTS" text is uWS's own fallback message; the real error is `LoadLibraryExW failed`, which tells the user nothing actionable. ## Root cause uWS's prebuilt Windows `.node` (`uws_win32_x64_{108,115,127}.node`) is **not a Node-API addon**. Inspecting its PE import table (`objdump -p`) shows a **regular, non delay-load import of `node.exe`** that pulls in: - raw **V8 C++ ABI** symbols (`v8::Object::New`, `HandleScope`, `FunctionTemplate`, …) - **Node.js internals** (`node::MakeCallback`, `node::AddEnvironmentCleanupHook`, `node::GetCurrentEventLoop`) - **libuv** (`uv_run`, `uv_async_init`, …) and **zlib** The Windows loader resolves an import of `node.exe` by module name at `LoadLibraryExW` time, so it only succeeds when the host process is literally named `node.exe`. Loaded into `deno.exe` (or any other host — this is also why it breaks in Node SEA, Bun and Electron), the import can't be satisfied and the load fails. Deno cannot make such an addon work: it doesn't (and can't) export V8's C++ ABI, Node's internal C++ API, or a real libuv event loop. The only correct outcome is a clear diagnostic. ## Fix Mirrors the legacy V8/nan addon diagnostic added in #34683. - New dependency-free, bounds-checked PE import-table reader in `ext/napi/pe.rs`. `imports_node_executable()` parses the **regular** import directory and checks for a `node.exe` import (case-insensitive). It is unit-tested with a synthetic PE builder and was validated against the real uWS binaries (output matches `objdump` exactly). - New `NApiError::UnsupportedNodeBinaryAddon`. On Windows, when `Library::load_with_flags` fails, the addon is inspected; if it imports `node.exe` directly, Deno now reports: > Cannot load native addon at &lt;path&gt;: it links directly against the Node.js binary (node.exe) and relies on the V8 C++ ABI, Node.js internals and/or libuv exported by that executable, none of which Deno provides. Only Node-API (N-API) addons are supported. ... **Delay-loaded** `node.exe` imports (the node-gyp default, redirected to the host at runtime via `win_delay_load_hook`) are intentionally ignored — those resolve against the host's exported N-API symbols and work fine in Deno. ## Testing - `cargo test -p deno_napi --lib pe::` — 4 unit tests (real-binary-shaped fixtures + malformed input). - `cargo clippy -p deno_napi --all-targets` and `cargo clippy -p deno_napi --target x86_64-pc-windows-msvc` both clean (the new load-failure arm is Windows-only). Refs #25956 Closes denoland/divybot#409 --------- Co-authored-by: divybot <divybot@users.noreply.github.com> Co-authored-by: Divy Srivastava <me@littledivy.com>
Author
Parents
Loading