Skip to content

Commit fc07931

Browse files
giodl73-repoCopilot
andcommitted
fix(update): require integer timeout values
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 3d85e84 commit fc07931

2 files changed

Lines changed: 45 additions & 4 deletions

File tree

src/cli/update-cli/shared.command-runner.test.ts

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { beforeEach, describe, expect, it, vi } from "vitest";
2-
import { createGlobalCommandRunner } from "./shared.js";
2+
import { defaultRuntime } from "../../runtime.js";
3+
import { createGlobalCommandRunner, parseTimeoutMsOrExit } from "./shared.js";
34

45
const runCommandWithTimeout = vi.hoisted(() => vi.fn());
56

@@ -48,4 +49,40 @@ describe("createGlobalCommandRunner", () => {
4849
code: 17,
4950
});
5051
});
52+
53+
it("requires timeout values to be complete positive integer seconds", () => {
54+
const error = vi.spyOn(defaultRuntime, "error").mockImplementation(() => undefined);
55+
const exit = vi.spyOn(defaultRuntime, "exit").mockImplementation(() => undefined as never);
56+
57+
try {
58+
expect(parseTimeoutMsOrExit("1.5")).toBeNull();
59+
expect(parseTimeoutMsOrExit("10abc")).toBeNull();
60+
expect(parseTimeoutMsOrExit("0")).toBeNull();
61+
expect(parseTimeoutMsOrExit("-1")).toBeNull();
62+
63+
expect(error).toHaveBeenCalledTimes(4);
64+
expect(error).toHaveBeenCalledWith("--timeout must be a positive integer (seconds)");
65+
expect(exit).toHaveBeenCalledTimes(4);
66+
expect(exit).toHaveBeenCalledWith(1);
67+
} finally {
68+
error.mockRestore();
69+
exit.mockRestore();
70+
}
71+
});
72+
73+
it("parses complete positive integer timeout values as milliseconds", () => {
74+
const error = vi.spyOn(defaultRuntime, "error").mockImplementation(() => undefined);
75+
const exit = vi.spyOn(defaultRuntime, "exit").mockImplementation(() => undefined as never);
76+
77+
try {
78+
expect(parseTimeoutMsOrExit(" 10 ")).toBe(10_000);
79+
expect(parseTimeoutMsOrExit("001")).toBe(1_000);
80+
expect(parseTimeoutMsOrExit()).toBeUndefined();
81+
expect(error).not.toHaveBeenCalled();
82+
expect(exit).not.toHaveBeenCalled();
83+
} finally {
84+
error.mockRestore();
85+
exit.mockRestore();
86+
}
87+
});
5188
});

src/cli/update-cli/shared.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,17 @@ export type UpdateWizardOptions = {
5454
const INVALID_TIMEOUT_ERROR = "--timeout must be a positive integer (seconds)";
5555

5656
export function parseTimeoutMsOrExit(timeout?: string): number | undefined | null {
57-
const timeoutMs = timeout ? Number.parseInt(timeout, 10) * 1000 : undefined;
58-
if (timeoutMs !== undefined && (Number.isNaN(timeoutMs) || timeoutMs <= 0)) {
57+
const trimmed = timeout?.trim();
58+
if (!trimmed) {
59+
return undefined;
60+
}
61+
const seconds = Number(trimmed);
62+
if (!/^\d+$/u.test(trimmed) || !Number.isSafeInteger(seconds) || seconds <= 0) {
5963
defaultRuntime.error(INVALID_TIMEOUT_ERROR);
6064
defaultRuntime.exit(1);
6165
return null;
6266
}
63-
return timeoutMs;
67+
return seconds * 1000;
6468
}
6569

6670
const OPENCLAW_REPO_URL = "https://github.com/openclaw/openclaw.git";

0 commit comments

Comments
 (0)