Fence process.env mutations during extension startup#325460
Fence process.env mutations during extension startup#325460arvindashtekar wants to merge 2 commits into
Conversation
There was a problem hiding this comment.
Pull request overview
This PR adds a “fence” around process.env during Node extension startup so that synchronous environment mutations made during CommonJS module evaluation and the synchronous portion of activate() don’t leak to other extensions sharing the same extension host process.
Changes:
- Introduces
runWithFencedProcessEnvironmentto snapshot/restoreprocess.envaround a synchronous callback (including restoration on throw). - Wraps CommonJS
require()evaluation and the synchronous portion of extension activation with the environment fence in the Node extension host. - Adds Node-side regression tests covering restoration for successful and throwing callbacks.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| src/vs/workbench/api/test/node/extHostProcessEnvironment.test.ts | Adds focused unit tests verifying environment snapshot/restore behavior (success + throw). |
| src/vs/workbench/api/node/extHostProcessEnvironment.ts | Introduces the environment-fencing helper that snapshots and restores process.env. |
| src/vs/workbench/api/node/extHostExtensionService.ts | Applies the fence to CommonJS module loading and wraps the synchronous portion of _callActivate. |
| src/vs/workbench/api/common/extHostExtensionService.ts | Adds an overridable _callActivate instance hook so Node can fence activation without changing common logic. |
|
@arvindashtekar please read the following Contributor License Agreement(CLA). If you agree with the CLA, please reply with the following information.
Contributor License AgreementContribution License AgreementThis Contribution License Agreement (“Agreement”) is agreed to by the party signing below (“You”),
|
Fixes #325459
What changed
activate()callWhy
Desktop extensions share one Node extension-host process. A dependency loaded by one extension can mutate
process.envand leave that value visible to unrelated extensions and any child processes they launch. In the reported case,DEBUG=releasepropagated into Gradle and was interpreted by Spring Boot as its global debug switch.The fence restores the host environment before synchronous extension startup yields control, preventing this class of startup-time mutation from escaping to another extension.
The change deliberately does not wrap asynchronous ESM evaluation or asynchronous continuations. Those can overlap concurrent extension activations, so snapshot restoration there could overwrite legitimate host changes and requires a broader isolation design.
Validation
npm run typecheck-clientscripts\test.bat --runGlob **/extHostProcessEnvironment.test.jsnpm run eslintnpm run valid-layers-checkThe full
npm run hygienetask could not complete on this Windows checkout because its package checker constructed a duplicated drive prefix forremote/package.json. The staged-file pre-commit hygiene checks passed.