From 04fb7dfca8b596708384637ec85e521446817afc Mon Sep 17 00:00:00 2001 From: cgoing Date: Tue, 8 Apr 2025 00:02:13 +0900 Subject: [PATCH 1/5] fix (core): prevent mutation of customEnv by creating a copy --- packages/ai/mcp-stdio/get-environment.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/ai/mcp-stdio/get-environment.ts b/packages/ai/mcp-stdio/get-environment.ts index 843d7edb41e9..d22b7f854caf 100644 --- a/packages/ai/mcp-stdio/get-environment.ts +++ b/packages/ai/mcp-stdio/get-environment.ts @@ -24,7 +24,7 @@ export function getEnvironment( ] : ['HOME', 'LOGNAME', 'PATH', 'SHELL', 'TERM', 'USER']; - const env: Record = customEnv ?? {}; + const env: Record = customEnv ? { ...customEnv } : {}; for (const key of DEFAULT_INHERITED_ENV_VARS) { const value = globalThis.process.env[key]; From 8c46fc0b5f2e6747e0248475640b065cc13ab569 Mon Sep 17 00:00:00 2001 From: cgoing Date: Tue, 8 Apr 2025 00:40:37 +0900 Subject: [PATCH 2/5] test (ai/mcp): add test to ensure original environment object is not mutated --- .changeset/fix-env-mutation.md | 5 +++++ .../ai/mcp-stdio/create-child-process.test.ts | 16 ++++++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 .changeset/fix-env-mutation.md diff --git a/.changeset/fix-env-mutation.md b/.changeset/fix-env-mutation.md new file mode 100644 index 000000000000..a083e32cbdc4 --- /dev/null +++ b/.changeset/fix-env-mutation.md @@ -0,0 +1,5 @@ +--- +"@ai/core": patch +--- + +Fix Environment Object Mutation in `get-environment.ts` \ No newline at end of file diff --git a/packages/ai/mcp-stdio/create-child-process.test.ts b/packages/ai/mcp-stdio/create-child-process.test.ts index 4bd899bd7b35..66f17a96316c 100644 --- a/packages/ai/mcp-stdio/create-child-process.test.ts +++ b/packages/ai/mcp-stdio/create-child-process.test.ts @@ -52,6 +52,22 @@ describe('createChildProcess', () => { childProcessWithCustomEnv.kill(); }); + it('should not mutate the original environment object', async () => { + const originalConfig = { + command: process.execPath, + env: { CUSTOM_VAR: 'custom_value' }, + }; + const originalConfigCopy = JSON.parse(JSON.stringify(originalConfig)); + + const childProcessWithCustomEnv = await createChildProcess( + originalConfig, + new AbortController().signal, + ); + + expect(originalConfig.env).toEqual(originalConfigCopy.env); + childProcessWithCustomEnv.kill(); + }); + it('should spawn a child process with args', async () => { const childProcessWithArgs = await createChildProcess( { command: process.execPath, args: ['-c', 'echo', 'test'] }, From 8098563362ed05a1528b9dd2003a0f423d7c9bb6 Mon Sep 17 00:00:00 2001 From: cgoing Date: Tue, 8 Apr 2025 00:52:31 +0900 Subject: [PATCH 3/5] Revert "test (ai/mcp): add test to ensure original environment object is not mutated" This reverts commit 8c46fc0b5f2e6747e0248475640b065cc13ab569. --- .changeset/fix-env-mutation.md | 5 ----- .../ai/mcp-stdio/create-child-process.test.ts | 16 ---------------- 2 files changed, 21 deletions(-) delete mode 100644 .changeset/fix-env-mutation.md diff --git a/.changeset/fix-env-mutation.md b/.changeset/fix-env-mutation.md deleted file mode 100644 index a083e32cbdc4..000000000000 --- a/.changeset/fix-env-mutation.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@ai/core": patch ---- - -Fix Environment Object Mutation in `get-environment.ts` \ No newline at end of file diff --git a/packages/ai/mcp-stdio/create-child-process.test.ts b/packages/ai/mcp-stdio/create-child-process.test.ts index 66f17a96316c..4bd899bd7b35 100644 --- a/packages/ai/mcp-stdio/create-child-process.test.ts +++ b/packages/ai/mcp-stdio/create-child-process.test.ts @@ -52,22 +52,6 @@ describe('createChildProcess', () => { childProcessWithCustomEnv.kill(); }); - it('should not mutate the original environment object', async () => { - const originalConfig = { - command: process.execPath, - env: { CUSTOM_VAR: 'custom_value' }, - }; - const originalConfigCopy = JSON.parse(JSON.stringify(originalConfig)); - - const childProcessWithCustomEnv = await createChildProcess( - originalConfig, - new AbortController().signal, - ); - - expect(originalConfig.env).toEqual(originalConfigCopy.env); - childProcessWithCustomEnv.kill(); - }); - it('should spawn a child process with args', async () => { const childProcessWithArgs = await createChildProcess( { command: process.execPath, args: ['-c', 'echo', 'test'] }, From c025bf6734caa8cdbd46606edc8d5f4048ea803b Mon Sep 17 00:00:00 2001 From: cgoing Date: Tue, 8 Apr 2025 01:21:56 +0900 Subject: [PATCH 4/5] test (ai/mcp): add test to ensure original environment object is not mutated --- .changeset/fix-env-mutation.md | 5 +++++ packages/ai/mcp-stdio/get-environment.test.ts | 13 +++++++++++++ 2 files changed, 18 insertions(+) create mode 100644 .changeset/fix-env-mutation.md create mode 100644 packages/ai/mcp-stdio/get-environment.test.ts diff --git a/.changeset/fix-env-mutation.md b/.changeset/fix-env-mutation.md new file mode 100644 index 000000000000..92454ae660df --- /dev/null +++ b/.changeset/fix-env-mutation.md @@ -0,0 +1,5 @@ +--- +'@ai/core': patch +--- + +fix (ai/mcp): prevent mutation of customEnv diff --git a/packages/ai/mcp-stdio/get-environment.test.ts b/packages/ai/mcp-stdio/get-environment.test.ts new file mode 100644 index 000000000000..69c40c86cf9c --- /dev/null +++ b/packages/ai/mcp-stdio/get-environment.test.ts @@ -0,0 +1,13 @@ +import { describe, it, expect } from 'vitest'; +import { getEnvironment } from './get-environment'; + +describe('getEnvironment', () => { + it('should not mutate the original custom environment object', () => { + const customEnv = { CUSTOM_VAR: 'custom_value' }; + + const result = getEnvironment(customEnv); + + expect(customEnv).toEqual({ CUSTOM_VAR: 'custom_value' }); + expect(result).not.toBe(customEnv); + }); +}); From 191d142b411c679405c79090b967f866ae7f0556 Mon Sep 17 00:00:00 2001 From: cgoing Date: Tue, 8 Apr 2025 01:36:10 +0900 Subject: [PATCH 5/5] test (ai/mcp): update expectation to use toStrictEqual for custom environment object --- packages/ai/mcp-stdio/get-environment.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/ai/mcp-stdio/get-environment.test.ts b/packages/ai/mcp-stdio/get-environment.test.ts index 69c40c86cf9c..1ea0bb900766 100644 --- a/packages/ai/mcp-stdio/get-environment.test.ts +++ b/packages/ai/mcp-stdio/get-environment.test.ts @@ -7,7 +7,7 @@ describe('getEnvironment', () => { const result = getEnvironment(customEnv); - expect(customEnv).toEqual({ CUSTOM_VAR: 'custom_value' }); + expect(customEnv).toStrictEqual({ CUSTOM_VAR: 'custom_value' }); expect(result).not.toBe(customEnv); }); });