fix(node-pty): patch winpty.gyp paths and harden POSIX spawn errors#963
fix(node-pty): patch winpty.gyp paths and harden POSIX spawn errors#963feldsys wants to merge 1 commit intoRunMaestro:rcfrom
Conversation
Two fixes against node-pty 1.1.0 to make the Windows + macOS native
build paths reliable:
- winpty.gyp: prefix the GetCommitHash.bat / UpdateGenVersion.bat
invocations with `.\` so cmd /c finds them when CWD lookup
doesn't include the current directory (Windows build fix).
- pty_posix_spawn: surface the actual posix_spawnp errno via a
format_error helper and a std::string err out-param, instead of
collapsing every failure into the generic "posix_spawnp failed."
message. Initialise low_fds[3] = { -1, -1, -1 } and replace the
cleanup loop with a bounded, -1-aware variant so the early-exit
paths can't OOB-index or close uninitialised file descriptors.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
📝 WalkthroughWalkthroughThis patch updates the ChangesWindows Build Configuration
Unix PTY Error Propagation
Estimated Code Review Effort🎯 3 (Moderate) | ⏱️ ~25 minutes Suggested Labels
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
patches/node-pty+1.1.0.patch (1)
66-70: 💤 Low valueConsider
strerror_rfor thread safety; truncation is acceptable.
strerroris not thread-safe per POSIX. In practice this helper is invoked on the libuv/N-API main thread forPtyFork, so racing is unlikely, but ifnode-ptyever callspty_posix_spawnfrom worker threads in the future this becomes a latent issue. The 256-byte buffer is fine —snprintftruncates safely and the format string is short. Considerstrerror_r(XSI variant on Linux, POSIX on macOS) as a defensive future-proofing measure; not blocking.♻️ Optional: thread-safe variant
static std::string format_error(const char* func, int err_code) { char buf[256]; - snprintf(buf, sizeof(buf), "%s: %s", func, strerror(err_code)); + char errbuf[128]; +#if defined(__APPLE__) || defined(__GLIBC__) && ((_POSIX_C_SOURCE >= 200112L) && !_GNU_SOURCE) + strerror_r(err_code, errbuf, sizeof(errbuf)); + snprintf(buf, sizeof(buf), "%s: %s", func, errbuf); +#else + snprintf(buf, sizeof(buf), "%s: %s", func, strerror(err_code)); +#endif return buf; }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@patches/node-pty`+1.1.0.patch around lines 66 - 70, The helper format_error uses strerror which is not thread-safe; replace its use with the thread-safe strerror_r API in format_error to avoid races (keeping the existing 256-byte buffer and snprintf truncation behavior). Update the implementation of format_error to call strerror_r(buf, sizeof(buf), err_code) (handling both XSI and GNU variants if needed) and then format the final message with snprintf as before; ensure you still return a std::string and preserve the current message layout ("%s: %s").
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@patches/node-pty`+1.1.0.patch:
- Around line 66-70: The helper format_error uses strerror which is not
thread-safe; replace its use with the thread-safe strerror_r API in format_error
to avoid races (keeping the existing 256-byte buffer and snprintf truncation
behavior). Update the implementation of format_error to call strerror_r(buf,
sizeof(buf), err_code) (handling both XSI and GNU variants if needed) and then
format the final message with snprintf as before; ensure you still return a
std::string and preserve the current message layout ("%s: %s").
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: f1e24b48-0cd4-47f1-86d9-0df6af31a35e
📒 Files selected for processing (1)
patches/node-pty+1.1.0.patch
Greptile SummaryThis PR patches
Confidence Score: 4/5Safe to merge — the changes are tightly scoped to a patch file applied during The logic in the refactored patches/node-pty+1.1.0.patch — worth a manual Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A["pty_posix_spawn entry\nlow_fds initialized to -1,-1,-1\nacts and attrs init'd early"] --> B["Fill low_fds loop\nposix_openpt x3"]
B --> C["posix_openpt for master fd"]
C -- fails --> Z["set *err via format_error"]
C -- ok --> D["grantpt"]
D -- fails --> Z
D -- ok --> E["unlockpt"]
E -- fails --> Z
E -- ok --> F["ioctl TIOCPTYGNAME"]
F -- fails --> Z
F -- ok --> G["open slave pty"]
G -- fails --> Z
G -- ok --> H["tcsetattr + TIOCSWINSZ"]
H -- fails --> Z
H -- ok --> I["adddup2+addclose on acts"]
I --> J["posix_spawnattr_setflags\nsetsigdefault / setsigmask"]
J -- fails --> Z
J -- ok --> K["posix_spawn loop\nretry on EINTR"]
K -- fails --> Z
K -- ok --> L["spawn succeeded\nerr stays empty"]
Z --> N
L --> N["done label:\ndestroy acts+attrs\nclose slave if open\nclose low_fds != -1"]
N --> O["Return to PtyFork"]
O --> P{"err empty?"}
P -- yes --> Q["pty_nonblock master\nreturn pid+master to caller"]
P -- no --> R["close master if != -1\nthrow Napi::Error with message"]
Reviews (1): Last reviewed commit: "fix(node-pty): patch winpty.gyp paths an..." | Re-trigger Greptile |
|
Thanks for splitting this out, @feldsys — much easier to reason about in isolation. 🙏 Took a careful look at the patch:
CodeRabbit's Approving. ✅ |
Split out from #962 per @pedramamini's review — this commit is unrelated to the git graph / branch switcher feature and is easier to review and revert independently here.
Summary
Two fixes against the patched
node-pty@1.1.0:winpty.gyp(Windows build): prefix theGetCommitHash.bat/UpdateGenVersion.batinvocations with.\\socmd /cfinds them when the working directory isn't on the lookup path. Without this the native build fails on Windows.pty_posix_spawn(macOS error reporting): surface the actualposix_spawnperrno via aformat_errorhelper and astd::string errout-param, instead of collapsing every failure into the generic"posix_spawnp failed."string.CodeRabbit fix folded in
The original PR #962 version of this patch had an OOB / uninitialised-FD bug in the cleanup loop (CodeRabbit flagged it). This branch addresses it:
int low_fds[3] = { -1, -1, -1 };for (size_t i = 0; i <= count; i++) close(low_fds[i]);with a bounded,-1-aware variant that iterates0..3and skips uninitialised entries — no array OOB, noclose()on stack garbage.Why
node-ptyships an upstream patch viapatch-package. The Windows build silently breaks for new contributors without the gyp prefix fix, and a bare"posix_spawnp failed."made macOS spawn issues effectively unreproducible.Test plan
npm installon Windows applies the patch cleanly viapatch-package.npm installon macOS applies cleanly.Napi::Errorcarries the formatted"posix_spawn failed: <strerror>"instead of the legacy generic string.