Skip to content

process.env: Node-semantics exotic object on POSIX; coerce/validate/setenv-sync, first-wins dup load, typed-cache invalidate - #35882

Open
robobun wants to merge 16 commits into
mainfrom
claude/farm/729db18d/process-env-exotic-object
Open

process.env: Node-semantics exotic object on POSIX; coerce/validate/setenv-sync, first-wins dup load, typed-cache invalidate#35882
robobun wants to merge 16 commits into
mainfrom
claude/farm/729db18d/process-env-exotic-object

env_var::set_owned: lsan-ignore the leaked Box

246257b
Select commit
Loading
Failed to load commit list.
Claude / Claude Code Review completed Jul 26, 2026 in 36m 43s

Code review found 1 important issue

Found 3 candidates, confirmed 5. See review comments for details.

Details

Severity Count
🔴 Important 1
🟡 Nit 4
🟣 Pre-existing 0
Severity File:Line Issue
🔴 Important src/bun_core/env_var.rs:359-365 get_force_reload() can overwrite set_owned's Box with a musl-freeable environ pointer
🟡 Nit src/js/builtins/ProcessObjectInternals.ts:540-542 Windows deleteProperty trap: Symbol key handling not fixed alongside set/defineProperty
🟡 Nit src/bun_core/env_var.rs:836-839 reset() functions added by this PR are now dead code

Annotations

Check failure on line 365 in src/bun_core/env_var.rs

See this annotation in the file changed.

@claude claude / Claude Code Review

get_force_reload() can overwrite set_owned's Box with a musl-freeable environ pointer

The 5143c3e0 musl fix is incomplete: `set_owned()` covers the write path, but `get_force_reload()` (taken whenever `get_cached()==Unknown`) still calls `getenv_z()` and unconditionally stores the raw environ pointer via `deser_and_invalidate()`, and can overwrite `set_owned`'s Box. If an off-thread first read blocks on `ENVIRON_LOCK.read()` while main runs `setenv`+`set_owned`, it unblocks, reads the musl-allocated string S1, and writes S1 into the cache; main's next `process.env` write then fre

Check warning on line 542 in src/js/builtins/ProcessObjectInternals.ts

See this annotation in the file changed.

@claude claude / Claude Code Review

Windows deleteProperty trap: Symbol key handling not fixed alongside set/defineProperty

The Windows Proxy `deleteProperty` trap still does `String(p).toUpperCase()` on Symbol keys, so `delete process.env[Symbol('x')]` computes `k = "SYMBOL(X)"`, calls `editWindowsEnvVar("SYMBOL(X)", null)` (spurious `SetEnvironmentVariableW`), and returns `false` — throwing TypeError in strict mode. Node's `EnvDeleter` and this PR's new POSIX `JSProcessEnvMap::deleteProperty` both return `true` with no side effects for a Symbol key. This PR added the explicit `typeof p === "symbol"` guard to the si

Check warning on line 839 in src/bun_core/env_var.rs

See this annotation in the file changed.

@claude claude / Claude Code Review

reset() functions added by this PR are now dead code

The four `reset()` functions this PR adds (module-level `pub fn reset()` here, plus `string::Cache::reset()` at 409-413, `boolean::Cache::reset()` at 494-498, `unsigned::Cache::reset()` at 670-673) have zero callers: 5143c3e0f1 switched `invalidate_for_setenv()` from `$v::reset()` to `$v::set_owned(value)`, orphaning them. REVIEW.md: "Delete dead code in the same PR that makes it dead — helpers whose last caller you rewired". More importantly, this `reset()`'s doc comment ("Drop the cached value