fix(node/child_process): don't crash on undefined/null value of an env var (#20378)

Fixes #20373

---------

Co-authored-by: Bartek Iwańczuk <biwanczuk@gmail.com>
This commit is contained in:
zuisong 2023-09-05 18:42:35 +08:00 committed by GitHub
parent 2a1ba2732e
commit 4a561f12db
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 64 additions and 2 deletions

View file

@ -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");
});

View file

@ -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,