diff --git a/src/adapters/command-code.ts b/src/adapters/command-code.ts index ce20edf3312..d8327862ef6 100644 --- a/src/adapters/command-code.ts +++ b/src/adapters/command-code.ts @@ -160,7 +160,9 @@ async function gitWorkspaceInfo(cwd: string | undefined): Promise => { try { - const { stdout } = await execFile("git", args, { cwd, encoding: "utf8", timeout: 2000, windowsHide: true }); + // `git status` may invoke a repository-configured fsmonitor. Disable it for every + // metadata read so inspecting an untrusted workspace cannot launch local commands. + const { stdout } = await execFile("git", ["-c", "core.fsmonitor=false", ...args], { cwd, encoding: "utf8", timeout: 2000, windowsHide: true }); return stdout.trim(); } catch { return ""; diff --git a/tests/command-code-provider.test.ts b/tests/command-code-provider.test.ts index 4220cbcbd7e..f54af8453ac 100644 --- a/tests/command-code-provider.test.ts +++ b/tests/command-code-provider.test.ts @@ -1,4 +1,8 @@ import { afterEach, describe, expect, test } from "bun:test"; +import { execFileSync } from "node:child_process"; +import { chmod, mkdtemp, readFile, rm, writeFile } from "node:fs/promises"; +import { tmpdir } from "node:os"; +import { join } from "node:path"; import { createCommandCodeAdapter } from "../src/adapters/command-code"; import { loginCommandCode, parseCommandCodeCallback, shouldImportLocalCommandCodeAuth } from "../src/oauth/command-code"; import { buildModelsRequest, OAUTH_PROVIDERS } from "../src/oauth"; @@ -199,6 +203,27 @@ describe("Command Code provider", () => { expect(body.config.currentBranch).not.toBe(""); }); + test.skipIf(process.platform === "win32")("does not execute a repository-configured fsmonitor while collecting metadata", async () => { + const workspace = await mkdtemp(join(tmpdir(), "ocx-command-code-")); + const marker = join(workspace, "fsmonitor-ran"); + const monitor = join(workspace, "fsmonitor.sh"); + const previousCwd = process.cwd(); + try { + await writeFile(monitor, `#!/bin/sh\nprintf invoked > ${JSON.stringify(marker)}\n`); + await chmod(monitor, 0o755); + execFileSync("git", ["init", "-q"], { cwd: workspace }); + execFileSync("git", ["config", "core.fsmonitor", monitor], { cwd: workspace }); + + process.chdir(workspace); + const built = await builtRequest(parsed()); + expect(JSON.parse(built.body).config.isGitRepo).toBe(true); + await expect(readFile(marker, "utf8")).rejects.toThrow(); + } finally { + process.chdir(previousCwd); + await rm(workspace, { recursive: true, force: true }); + } + }); + test("does not advertise an unverified effort for models absent from the official table", async () => { const built = await builtRequest(parsed("moonshotai/Kimi-K3")); expect(JSON.parse(built.body).params).not.toHaveProperty("reasoning_effort");