diff options
-rw-r--r-- | cli/tests/unit_node/child_process_test.ts | 57 | ||||
-rw-r--r-- | ext/node/polyfills/internal/child_process.ts | 9 |
2 files changed, 64 insertions, 2 deletions
diff --git a/cli/tests/unit_node/child_process_test.ts b/cli/tests/unit_node/child_process_test.ts index 9abd5c1e6..a282977e0 100644 --- a/cli/tests/unit_node/child_process_test.ts +++ b/cli/tests/unit_node/child_process_test.ts @@ -13,7 +13,7 @@ import { import { Deferred, deferred } from "../../../test_util/std/async/deferred.ts"; import * as path from "../../../test_util/std/path/mod.ts"; -const { spawn, execFile, execFileSync, ChildProcess } = CP; +const { spawn, spawnSync, execFile, execFileSync, ChildProcess } = CP; function withTimeout<T>(timeoutInMS = 10_000): Deferred<T> { const promise = deferred<T>(); @@ -640,3 +640,58 @@ Deno.test({ assertEquals(cp.signalCode, "SIGIOT"); }, }); + +// Regression test for https://github.com/denoland/deno/issues/20373 +Deno.test(async function undefinedValueInEnvVar() { + const promise = withTimeout<string>(); + const env = spawn( + `"${Deno.execPath()}" eval -p "Deno.env.toObject().BAZ"`, + { + env: { + BAZ: "BAZ", + NO_COLOR: "true", + UNDEFINED_ENV: undefined, + // deno-lint-ignore no-explicit-any + NULL_ENV: null as any, + }, + shell: true, + }, + ); + try { + let envOutput = ""; + + assert(env.stdout); + env.on("error", (err: Error) => promise.reject(err)); + env.stdout.on("data", (data) => { + envOutput += data; + }); + env.on("close", () => { + promise.resolve(envOutput.trim()); + }); + await promise; + } finally { + env.kill(); + } + const value = await promise; + assertEquals(value, "BAZ"); +}); + +// Regression test for https://github.com/denoland/deno/issues/20373 +Deno.test(function spawnSyncUndefinedValueInEnvVar() { + const ret = spawnSync( + `"${Deno.execPath()}" eval -p "Deno.env.toObject().BAZ"`, + { + env: { + BAZ: "BAZ", + NO_COLOR: "true", + UNDEFINED_ENV: undefined, + // deno-lint-ignore no-explicit-any + NULL_ENV: null as any, + }, + shell: true, + }, + ); + + assertEquals(ret.status, 0); + assertEquals(ret.stdout.toString("utf-8").trim(), "BAZ"); +}); diff --git a/ext/node/polyfills/internal/child_process.ts b/ext/node/polyfills/internal/child_process.ts index b11281fd7..33b0b3166 100644 --- a/ext/node/polyfills/internal/child_process.ts +++ b/ext/node/polyfills/internal/child_process.ts @@ -53,6 +53,13 @@ export function mapValues<T, O>( const entries = Object.entries(record); for (const [key, value] of entries) { + if (typeof value === "undefined") { + continue; + } + if (value === null) { + continue; + } + const mappedValue = transformer(value); ret[key] = mappedValue; @@ -836,7 +843,7 @@ export function spawnSync( const output = new Deno.Command(command, { args, cwd, - env, + env: mapValues(env, (value) => value.toString()), stdout: toDenoStdio(normalizedStdio[1]), stderr: toDenoStdio(normalizedStdio[2]), uid, |