fix(codex-config): stop rejecting env values that start with "-"
--env's value is the RHS of one KEY=VALUE argv element, never its own argv position, so a leading "-" can never be parsed as a flag — unlike the key, which stays validated as an identifier. assertArg's leading-dash guard was reused for the value too, refusing ordinary values like "-1". Split it into assertEnvValue (no leading-dash check) for values only.
This commit is contained in:
@@ -189,6 +189,20 @@ describe("codex-cli argv construction", () => {
|
||||
}
|
||||
});
|
||||
|
||||
it("accepts an env value starting with '-' — it's the RHS of one KEY=VALUE argv element, never a flag", async () => {
|
||||
const restore = stubCodex();
|
||||
try {
|
||||
const result = await cli.mcpAdd({
|
||||
name: "docs",
|
||||
command: "node",
|
||||
env: { OFFSET: "-1" },
|
||||
});
|
||||
assert.deepEqual(argvOf(result), ["mcp", "add", "docs", "--env", "OFFSET=-1", "--", "node"]);
|
||||
} finally {
|
||||
restore();
|
||||
}
|
||||
});
|
||||
|
||||
it("builds mcp list / remove argvs", async () => {
|
||||
const restore = stubCodex();
|
||||
try {
|
||||
|
||||
+19
-1
@@ -94,6 +94,24 @@ function assertEnvKey(value, label) {
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* An environment variable VALUE. Unlike `assertArg`, a leading "-" is fine:
|
||||
* the value is the right-hand side of one `KEY=VALUE` argv element (built
|
||||
* by envFlags below), never its own argv position, so it can never be
|
||||
* parsed as a flag. Rejecting it anyway (as `assertArg` would) refused
|
||||
* ordinary values like "-1" or a base64 string that happens to start with
|
||||
* "-" for no real reason.
|
||||
*/
|
||||
function assertEnvValue(value, label) {
|
||||
if (typeof value !== "string") throw makeError("EBADARG", `${label} is required`);
|
||||
if (value.length > 512) throw makeError("EBADARG", `${label} is too long`);
|
||||
// eslint-disable-next-line no-control-regex
|
||||
if (/[\u0000-\u001f\u007f]/.test(value)) {
|
||||
throw makeError("EBADARG", `${label} contains control characters`);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/** An http(s) URL — `new URL()` both validates and normalizes the parse. */
|
||||
function assertUrl(value, label) {
|
||||
assertArg(value, label);
|
||||
@@ -219,7 +237,7 @@ async function mcpAdd({ name, url, bearerTokenEnvVar, command, args = [], env })
|
||||
const cmdArgs = args.map((a, i) => assertArg(a, `args[${i}]`));
|
||||
const envFlags = Object.entries(env || {}).flatMap(([k, v]) => {
|
||||
const key = assertEnvKey(k, "env key");
|
||||
assertArg(String(v), `env.${k}`);
|
||||
assertEnvValue(String(v), `env.${k}`);
|
||||
return ["--env", `${key}=${v}`];
|
||||
});
|
||||
return serialize(() => runCodex(["mcp", "add", n, ...envFlags, "--", cmd, ...cmdArgs]));
|
||||
|
||||
Reference in New Issue
Block a user