fix(qa): reject loose cron cleanup probe pids · openclaw/openclaw@2c7c6fe
vincentkoc
·
2026-06-17
·
via Recent Commits to openclaw:main
| Original file line number | Diff line number | Diff line change |
|---|
@@ -35,11 +35,18 @@ export function assertCronFinishedOk(finished: CronFinishedPayload | undefined):
|
35 | 35 | } |
36 | 36 | } |
37 | 37 | |
| 38 | +function parseProbePid(raw: string): number | undefined { |
| 39 | +const text = raw.trim(); |
| 40 | +if (!/^[1-9]\d*$/u.test(text)) { |
| 41 | +return undefined; |
| 42 | +} |
| 43 | +const pid = Number(text); |
| 44 | +return Number.isSafeInteger(pid) ? pid : undefined; |
| 45 | +} |
| 46 | + |
38 | 47 | async function readProbePid(pidPath: string): Promise<number | undefined> { |
39 | 48 | try { |
40 | | -const raw = (await fs.readFile(pidPath, "utf-8")).trim(); |
41 | | -const pid = Number.parseInt(raw, 10); |
42 | | -return Number.isInteger(pid) && pid > 0 ? pid : undefined; |
| 49 | +return parseProbePid(await fs.readFile(pidPath, "utf-8")); |
43 | 50 | } catch { |
44 | 51 | return undefined; |
45 | 52 | } |
@@ -51,8 +58,8 @@ async function readProbePids(pidsPath: string): Promise<number[]> {
|
51 | 58 | const pids: number[] = []; |
52 | 59 | const seen = new Set<number>(); |
53 | 60 | for (const line of raw.split(/\r?\n/)) { |
54 | | -const pid = Number.parseInt(line.trim(), 10); |
55 | | -if (!Number.isInteger(pid) || pid <= 0 || seen.has(pid)) { |
| 61 | +const pid = parseProbePid(line); |
| 62 | +if (pid === undefined || seen.has(pid)) { |
56 | 63 | continue; |
57 | 64 | } |
58 | 65 | seen.add(pid); |
|
| Original file line number | Diff line number | Diff line change |
|---|
@@ -37,6 +37,20 @@ describe("cron MCP cleanup docker client", () => {
|
37 | 37 | } |
38 | 38 | }); |
39 | 39 | |
| 40 | +it("does not parse malformed probe pid prefixes", async () => { |
| 41 | +const root = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-cron-mcp-client-")); |
| 42 | +try { |
| 43 | +const pidPath = path.join(root, "probe.pid"); |
| 44 | +fs.writeFileSync(pidPath, "123abc\n", "utf8"); |
| 45 | + |
| 46 | +const startedAt = Date.now(); |
| 47 | +await expect(waitForProbePid(pidPath, { pollMs: 1, timeoutMs: 20 })).resolves.toBeUndefined(); |
| 48 | +expect(Date.now() - startedAt).toBeLessThan(1000); |
| 49 | +} finally { |
| 50 | +fs.rmSync(root, { force: true, recursive: true }); |
| 51 | +} |
| 52 | +}); |
| 53 | + |
40 | 54 | it("accepts cron finished events only when the run status is ok", () => { |
41 | 55 | expect(() => assertCronFinishedOk({ status: "ok" })).not.toThrow(); |
42 | 56 | expect(() => assertCronFinishedOk({ status: "error" })).toThrow( |
|
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。