deno
ef1460d4 - fix(ext/process): run shebang-less scripts via /bin/sh on ENOEXEC (#34945)

Commit
97 days ago
fix(ext/process): run shebang-less scripts via /bin/sh on ENOEXEC (#34945) Running a script that the kernel can't exec directly (e.g. a shell script without a `#!` shebang line) via `child_process.execFileSync`/`spawn` failed on **Linux** with `Command failed`/`ENOEXEC`, while it works in Node.js: ```js import { execFileSync } from "node:child_process"; // helpers/script.sh contains: echo "$1 $1" (with NO shebang line) execFileSync("./helpers/script.sh", ["hello"], { encoding: "utf8" }); // Node: "hello hello" — Deno (Linux): Error: Command failed ``` ## Root cause POSIX `execvp`/`posix_spawnp` are specified to fall back to running a file that exec rejects with `ENOEXEC` through `/bin/sh`. **macOS** libc implements this fallback (verified with a C repro), so `Deno.Command`/`execFileSync` already worked there — the bug only reproduces on **Linux**, where **glibc**'s `posix_spawnp` (used by Rust's `std::process::Command`) does *not* fall back. Node.js gets the fallback for free because libuv spawns via `execvp`. ## Fix When a spawn fails with `ENOEXEC`, retry the command as an argument to `/bin/sh`, matching Node.js/libuv. This is applied at all three spawn paths in `ext/process` — `Deno.Command().outputSync()`, `Deno.Command().spawn()`, and the node-compat spawn op — so sync and async `spawn`/`spawnSync`/`exec`/`execFile` all behave consistently. Notes: - Permissions are still checked against the original command (not `/bin/sh`); the shell is only the interpreter, exactly as `execvp` does. No `--allow-run` bypass. - Files that are not executable still fail with a permission error (`EACCES`, not `ENOEXEC`), so they are *not* silently run through the shell — matching Node. - Windows is unaffected. ## Test Added `tests/specs/node/exec_file_sync_no_shebang` (unix-only) covering `execFileSync`, `spawnSync`, async `execFile`/`spawn`, and `Deno.Command`. Closes #34919 Closes denoland/divybot#503 --------- Co-authored-by: divybot <divybot@users.noreply.github.com> Co-authored-by: Divy Srivastava <me@littledivy.com>
Author
Parents
Loading