Skip to content

Commit 4ab81cf

Browse files
authored
fix: substitute every ${VAR} reference when merging env files (#1829)
## Problem `mergeEnvVariables` expands `${VAR}` references in env file values (the `python.envFile` file, the project `.env` and API overrides) with `String.prototype.replace` and a string pattern. That has two effects: - Only the first reference to a variable is replaced. With `ROOT=/home/user` in the base environment, `PATHS=${ROOT}/a:${ROOT}/b` becomes `/home/user/a:${ROOT}/b`. - `$` sequences in the substituted value are read as replacement patterns. A base value of `pa$$word` comes out as `pa$word`. ## Fix Use `split(token).join(value)`, which replaces every occurrence and inserts the value as is. (`replaceAll` is not available with the ES2020 lib target.) ## Tests Added `src/test/features/execution/envVarUtils.unit.test.ts`, which merges a value with a repeated `${ROOT}` reference and a `${SECRET}` whose base value contains `$$`. It fails before the fix (actual `/home/user/a:${ROOT}/b`) and passes after it. - `npm run unittest` (Windows, Node 24): 2430 passing, 4 pending. - eslint and prettier pass on the changed files.
1 parent 14cecd8 commit 4ab81cf

2 files changed

Lines changed: 14 additions & 1 deletion

File tree

‎src/features/execution/envVarUtils.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ export function mergeEnvVariables(
1717
Object.keys(base).forEach((baseKey) => {
1818
const baseValue = base[baseKey];
1919
if (baseValue) {
20-
value = value?.replace(`\${${baseKey}}`, baseValue);
20+
value = value?.split(`\${${baseKey}}`).join(baseValue);
2121
}
2222
});
2323
env[otherKey] = value;
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import * as assert from 'assert';
2+
import { mergeEnvVariables } from '../../../features/execution/envVarUtils';
3+
4+
suite('Env Var Utils Tests', () => {
5+
test('mergeEnvVariables substitutes every reference to a base variable', () => {
6+
const env = mergeEnvVariables(
7+
{ ROOT: '/home/user', SECRET: 'pa$$word' },
8+
{ A: '${ROOT}/a:${ROOT}/b', B: '${SECRET}' },
9+
);
10+
assert.strictEqual(env.A, '/home/user/a:/home/user/b');
11+
assert.strictEqual(env.B, 'pa$$word');
12+
});
13+
});

0 commit comments

Comments
 (0)