Skip to content

Commit 0f64e3c

Browse files
committed
fix(scripts): clamp secret proof timers
1 parent 6538823 commit 0f64e3c

2 files changed

Lines changed: 48 additions & 7 deletions

File tree

scripts/e2e/secret-provider-integrations.mjs

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,23 +21,24 @@ const MANUAL_EXEC_TOKEN = "proof-manual-exec-token";
2121
const PLUGIN_EXEC_TOKEN = "proof-plugin-exec-token";
2222
const OPENAI_PROFILE = "openai:secretref-proof";
2323
const OPENAI_LIVE_PROOF_MODEL = "openai/gpt-5.5";
24-
const COMMAND_TIMEOUT_MS = readPositiveInt(
24+
const MAX_SECRET_PROOF_TIMER_TIMEOUT_MS = 2_147_000_000;
25+
const COMMAND_TIMEOUT_MS = readPositiveTimerMs(
2526
process.env.OPENCLAW_SECRET_PROOF_COMMAND_MS,
2627
120000,
2728
"OPENCLAW_SECRET_PROOF_COMMAND_MS",
2829
);
2930
const COMMAND_TIMEOUT_KILL_GRACE_MS = 1000;
30-
const READY_TIMEOUT_MS = readPositiveInt(
31+
const READY_TIMEOUT_MS = readPositiveTimerMs(
3132
process.env.OPENCLAW_SECRET_PROOF_READY_MS,
3233
120000,
3334
"OPENCLAW_SECRET_PROOF_READY_MS",
3435
);
35-
const RPC_TIMEOUT_MS = readPositiveInt(
36+
const RPC_TIMEOUT_MS = readPositiveTimerMs(
3637
process.env.OPENCLAW_SECRET_PROOF_RPC_MS,
3738
15000,
3839
"OPENCLAW_SECRET_PROOF_RPC_MS",
3940
);
40-
const TEARDOWN_GRACE_MS = readPositiveInt(
41+
const TEARDOWN_GRACE_MS = readPositiveTimerMs(
4142
process.env.OPENCLAW_SECRET_PROOF_TEARDOWN_GRACE_MS,
4243
5000,
4344
"OPENCLAW_SECRET_PROOF_TEARDOWN_GRACE_MS",
@@ -101,6 +102,18 @@ function readPositiveInt(raw, fallback, label) {
101102
return parsed;
102103
}
103104

105+
function clampSecretProofTimerTimeoutMs(valueMs) {
106+
const value = Number.isFinite(valueMs) ? valueMs : 1;
107+
return Math.min(
108+
Math.max(1, Math.floor(value)),
109+
MAX_SECRET_PROOF_TIMER_TIMEOUT_MS,
110+
);
111+
}
112+
113+
function readPositiveTimerMs(raw, fallback, label) {
114+
return clampSecretProofTimerTimeoutMs(readPositiveInt(raw, fallback, label));
115+
}
116+
104117
function remainingDeadlineMs(started, timeoutMs) {
105118
return Math.max(1, timeoutMs - (Date.now() - started));
106119
}
@@ -347,7 +360,7 @@ async function cleanupEnv(root, options = {}) {
347360
}
348361

349362
function runCommand(command, args, options = {}) {
350-
const timeoutMs = options.timeoutMs ?? COMMAND_TIMEOUT_MS;
363+
const timeoutMs = clampSecretProofTimerTimeoutMs(options.timeoutMs ?? COMMAND_TIMEOUT_MS);
351364
return new Promise((resolve, reject) => {
352365
const usesProcessGroup = options.detached ?? process.platform !== "win32";
353366
const child = childProcess.spawn(command, args, {
@@ -1825,8 +1838,10 @@ async function runPtySecretsConfigurePreset(envCtx, options = {}) {
18251838
let timedOut = false;
18261839
let forceKillAt;
18271840
let forceKillTimer;
1828-
const timeoutMs = options.timeoutMs ?? 60000;
1829-
const timeoutKillGraceMs = options.timeoutKillGraceMs ?? COMMAND_TIMEOUT_KILL_GRACE_MS;
1841+
const timeoutMs = clampSecretProofTimerTimeoutMs(options.timeoutMs ?? 60000);
1842+
const timeoutKillGraceMs = clampSecretProofTimerTimeoutMs(
1843+
options.timeoutKillGraceMs ?? COMMAND_TIMEOUT_KILL_GRACE_MS,
1844+
);
18301845
const timer = setTimeout(() => {
18311846
timedOut = true;
18321847
signalPtyProcessTree(child, "SIGHUP");
@@ -2152,11 +2167,13 @@ async function main() {
21522167

21532168
export {
21542169
assertAllowedFailureCommandSucceeded,
2170+
clampSecretProofTimerTimeoutMs,
21552171
collectBlockingProofResults,
21562172
cleanupEnv,
21572173
expectGatewayStartupFails,
21582174
gatewayCall,
21592175
parseJsonOutput,
2176+
readPositiveTimerMs,
21602177
runPtySecretsConfigurePreset,
21612178
runWithProof,
21622179
runCommand,

test/scripts/secret-provider-integrations.test.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,30 @@ describe("secret provider integration proof harness", () => {
297297
}
298298
});
299299

300+
it("clamps oversized command timeout env values before scheduling timers", async () => {
301+
const previousTimeout = process.env.OPENCLAW_SECRET_PROOF_COMMAND_MS;
302+
process.env.OPENCLAW_SECRET_PROOF_COMMAND_MS = String(Number.MAX_SAFE_INTEGER);
303+
try {
304+
const proof = await import(
305+
`${pathToFileURL(proofScriptPath).href}?case=command-timeout-clamp-${Date.now()}`
306+
);
307+
308+
await expect(
309+
proof.runCommand(process.execPath, [
310+
"--input-type=module",
311+
"--eval",
312+
"setTimeout(() => process.exit(0), 25);",
313+
]),
314+
).resolves.toMatchObject({ code: 0 });
315+
} finally {
316+
if (previousTimeout === undefined) {
317+
delete process.env.OPENCLAW_SECRET_PROOF_COMMAND_MS;
318+
} else {
319+
process.env.OPENCLAW_SECRET_PROOF_COMMAND_MS = previousTimeout;
320+
}
321+
}
322+
});
323+
300324
it("parses JSON command output without swallowing brace-heavy diagnostics", async () => {
301325
const proof = await import(`${pathToFileURL(proofScriptPath).href}?case=json-${Date.now()}`);
302326

0 commit comments

Comments
 (0)