|
| 1 | +import fs from "node:fs"; |
| 2 | +import os from "node:os"; |
| 3 | +import path from "node:path"; |
1 | 4 | import { afterEach, beforeEach, describe, expect, it } from "vitest"; |
2 | 5 | import { captureEnv } from "../test-utils/env.js"; |
3 | 6 | import { resetProcessRegistryForTests } from "./bash-process-registry.js"; |
4 | 7 | import { createExecTool } from "./bash-tools.exec.js"; |
5 | 8 | |
6 | 9 | describe("exec security floor", () => { |
7 | 10 | let envSnapshot: ReturnType<typeof captureEnv>; |
| 11 | +let tempRoot: string | undefined; |
8 | 12 | |
9 | 13 | beforeEach(() => { |
10 | | -envSnapshot = captureEnv(["SHELL"]); |
| 14 | +envSnapshot = captureEnv([ |
| 15 | +"HOME", |
| 16 | +"USERPROFILE", |
| 17 | +"HOMEDRIVE", |
| 18 | +"HOMEPATH", |
| 19 | +"OPENCLAW_STATE_DIR", |
| 20 | +"SHELL", |
| 21 | +]); |
| 22 | +tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-exec-security-floor-")); |
| 23 | +process.env.HOME = tempRoot; |
| 24 | +process.env.USERPROFILE = tempRoot; |
| 25 | +process.env.OPENCLAW_STATE_DIR = path.join(tempRoot, "state"); |
| 26 | +if (process.platform === "win32") { |
| 27 | +const parsed = path.parse(tempRoot); |
| 28 | +process.env.HOMEDRIVE = parsed.root.slice(0, 2); |
| 29 | +process.env.HOMEPATH = tempRoot.slice(2) || "\\"; |
| 30 | +} else { |
| 31 | +delete process.env.HOMEDRIVE; |
| 32 | +delete process.env.HOMEPATH; |
| 33 | +} |
11 | 34 | resetProcessRegistryForTests(); |
12 | 35 | }); |
13 | 36 | |
14 | 37 | afterEach(() => { |
| 38 | +const dir = tempRoot; |
| 39 | +tempRoot = undefined; |
15 | 40 | envSnapshot.restore(); |
| 41 | +if (dir) { |
| 42 | +fs.rmSync(dir, { recursive: true, force: true }); |
| 43 | +} |
16 | 44 | }); |
17 | 45 | |
18 | 46 | it("ignores model-supplied allowlist security when configured security is full", async () => { |
|