Skip to content

Commit 7cfbd80

Browse files
committed
fix: address issue
1 parent a030037 commit 7cfbd80

4 files changed

Lines changed: 25 additions & 5 deletions

File tree

src/infra/dotenv.test.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -660,6 +660,10 @@ describe("workspace .env blocklist completeness", () => {
660660
"OPENCLAW_NODE_EXEC_HOST",
661661
"OPENCLAW_NODE_EXEC_FALLBACK",
662662
"OPENCLAW_ALLOW_PROJECT_LOCAL_BIN",
663+
"SystemRoot",
664+
"WINDIR",
665+
"ProgramFiles",
666+
"ProgramW6432",
663667
"SYNOLOGY_CHAT_INCOMING_URL",
664668
"SYNOLOGY_NAS_HOST",
665669
];

src/infra/dotenv.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,13 @@ const BLOCKED_WORKSPACE_DOTENV_KEYS = new Set([
7070
"OPENCLAW_TEST_TAILSCALE_BINARY",
7171
"PI_CODING_AGENT_DIR",
7272
"PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH",
73+
"PROGRAMFILES",
74+
"PROGRAMW6432",
7375
"SYNOLOGY_CHAT_INCOMING_URL",
7476
"SYNOLOGY_NAS_HOST",
77+
"SYSTEMROOT",
7578
"UV_PYTHON",
79+
"WINDIR",
7680
]);
7781

7882
// Block endpoint redirection for any service without overfitting per-provider names.

src/infra/restart-stale-pids.test.ts

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,10 @@ vi.mock("./windows-port-pids.js", () => ({
9090
mockReadWindowsProcessArgsResult(pid, timeoutMs),
9191
}));
9292

93+
vi.mock("./windows-install-roots.js", () => ({
94+
getWindowsInstallRoots: () => ({ systemRoot: "C:\\Windows" }),
95+
}));
96+
9397
import { resolveLsofCommandSync } from "./ports-lsof.js";
9498
let __testing: typeof import("./restart-stale-pids.js").__testing;
9599
let cleanStaleGatewayProcessesSync: typeof import("./restart-stale-pids.js").cleanStaleGatewayProcessesSync;
@@ -980,8 +984,10 @@ describe.skipIf(isWindows)("restart-stale-pids", () => {
980984

981985
it("does not report Windows pids as killed when taskkill fails", () => {
982986
const origDescriptor = Object.getOwnPropertyDescriptor(process, "platform");
987+
const originalSystemRoot = process.env.SystemRoot;
983988
const stalePid = process.pid + 911;
984989
Object.defineProperty(process, "platform", { value: "win32", configurable: true });
990+
process.env.SystemRoot = "C:\\PoisonedWindows";
985991
try {
986992
let fakeNow = 0;
987993
__testing.setDateNowOverride(() => fakeNow);
@@ -1012,12 +1018,17 @@ describe.skipIf(isWindows)("restart-stale-pids", () => {
10121018

10131019
expect(cleanStaleGatewayProcessesSync()).toEqual([]);
10141020
expect(mockSpawnSync).toHaveBeenCalledWith(
1015-
expect.stringContaining("taskkill.exe"),
1021+
"C:\\Windows\\System32\\taskkill.exe",
10161022
["/T", "/PID", String(stalePid)],
10171023
expect.objectContaining({ timeout: 5000 }),
10181024
);
10191025
} finally {
10201026
__testing.setDateNowOverride(null);
1027+
if (originalSystemRoot === undefined) {
1028+
delete process.env.SystemRoot;
1029+
} else {
1030+
process.env.SystemRoot = originalSystemRoot;
1031+
}
10211032
if (origDescriptor) {
10221033
Object.defineProperty(process, "platform", origDescriptor);
10231034
}
@@ -1063,13 +1074,13 @@ describe.skipIf(isWindows)("restart-stale-pids", () => {
10631074
expect(cleanStaleGatewayProcessesSync()).toEqual([]);
10641075
expect(mockSpawnSync).toHaveBeenNthCalledWith(
10651076
1,
1066-
expect.stringContaining("taskkill.exe"),
1077+
"C:\\Windows\\System32\\taskkill.exe",
10671078
["/T", "/PID", String(stalePid)],
10681079
expect.objectContaining({ timeout: 5000 }),
10691080
);
10701081
expect(mockSpawnSync).toHaveBeenNthCalledWith(
10711082
2,
1072-
expect.stringContaining("taskkill.exe"),
1083+
"C:\\Windows\\System32\\taskkill.exe",
10731084
["/F", "/T", "/PID", String(stalePid)],
10741085
expect.objectContaining({ timeout: 5000 }),
10751086
);

src/infra/restart-stale-pids.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { createSubsystemLogger } from "../logging/subsystem.js";
66
import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js";
77
import { isGatewayArgv } from "./gateway-process-argv.js";
88
import { resolveLsofCommandSync } from "./ports-lsof.js";
9+
import { getWindowsInstallRoots } from "./windows-install-roots.js";
910
import {
1011
readWindowsListeningPidsOnPortSync,
1112
readWindowsListeningPidsResultSync,
@@ -424,8 +425,8 @@ function terminateStaleProcessesSync(pids: number[]): number[] {
424425
* Sends a graceful taskkill first (/T for tree), waits, then escalates to /F.
425426
*/
426427
function terminateStaleProcessesWindows(pids: number[]): number[] {
427-
const taskkillPath = path.join(
428-
process.env.SystemRoot ?? "C:\\Windows",
428+
const taskkillPath = path.win32.join(
429+
getWindowsInstallRoots().systemRoot,
429430
"System32",
430431
"taskkill.exe",
431432
);

0 commit comments

Comments
 (0)