summaryrefslogtreecommitdiffhomepage
path: root/packages/tool-edit-file/src/edit-file.test.ts
diff options
context:
space:
mode:
authorAdam Malczewski <[email protected]>2026-06-21 23:32:23 +0900
committerAdam Malczewski <[email protected]>2026-06-21 23:32:23 +0900
commit7f6fd218ceeb3a1cf9420f5f6cfa4d70da6987bb (patch)
treee706f49d2df591c468fb66febe2a3f29d23cb0bb /packages/tool-edit-file/src/edit-file.test.ts
parent62ea07f56ff066bbf05041aadf8006cbc65e5c53 (diff)
downloaddispatch-7f6fd218ceeb3a1cf9420f5f6cfa4d70da6987bb.tar.gz
dispatch-7f6fd218ceeb3a1cf9420f5f6cfa4d70da6987bb.zip
feat: remove CWD path containment from file tools
read_file, write_file, and edit_file no longer restrict access to paths outside the working directory. The isPathWithinWorkdir prefix check and symlink hardening have been removed from all three tools. This allows agents to read and write files anywhere on the filesystem, not just within the per-turn cwd. The shell tool already had no such restriction.
Diffstat (limited to 'packages/tool-edit-file/src/edit-file.test.ts')
-rw-r--r--packages/tool-edit-file/src/edit-file.test.ts68
1 files changed, 1 insertions, 67 deletions
diff --git a/packages/tool-edit-file/src/edit-file.test.ts b/packages/tool-edit-file/src/edit-file.test.ts
index dba3d9e..5ef8376 100644
--- a/packages/tool-edit-file/src/edit-file.test.ts
+++ b/packages/tool-edit-file/src/edit-file.test.ts
@@ -3,12 +3,7 @@ import { tmpdir } from "node:os";
import { join } from "node:path";
import { createLogger, type ToolExecuteContext } from "@dispatch/kernel";
import { afterEach, beforeEach, describe, expect, it } from "vitest";
-import {
- computeReplacement,
- createEditFileTool,
- isPathWithinWorkdir,
- validateArgs,
-} from "./edit-file.js";
+import { computeReplacement, createEditFileTool, validateArgs } from "./edit-file.js";
function stubCtx(overrides?: Partial<ToolExecuteContext>): ToolExecuteContext {
return {
@@ -145,24 +140,6 @@ describe("computeReplacement", () => {
});
});
-describe("isPathWithinWorkdir", () => {
- it("accepts a path within workdir", () => {
- expect(isPathWithinWorkdir("/tmp/workdir/file.txt", "/tmp/workdir")).toBe(true);
- });
-
- it("accepts the workdir itself", () => {
- expect(isPathWithinWorkdir("/tmp/workdir", "/tmp/workdir")).toBe(true);
- });
-
- it("rejects a path outside workdir", () => {
- expect(isPathWithinWorkdir("/tmp/other/file.txt", "/tmp/workdir")).toBe(false);
- });
-
- it("rejects a prefix attack (workdir prefix but different dir)", () => {
- expect(isPathWithinWorkdir("/tmp/workdir-evil/file.txt", "/tmp/workdir")).toBe(false);
- });
-});
-
describe("createEditFileTool", () => {
it("replaces a single occurrence", async () => {
const filePath = join(workdir, "test.txt");
@@ -251,49 +228,6 @@ describe("createEditFileTool", () => {
expect(result.content).toContain("not found");
});
- it("rejects a path outside the working directory", async () => {
- const tool = createEditFileTool(workdir);
- const result = await tool.execute(
- { path: "../escape.txt", oldString: "a", newString: "b" },
- stubCtx(),
- );
-
- expect(result.isError).toBe(true);
- expect(result.content).toContain("outside the working directory");
- });
-
- it("rejects an absolute path outside workdir", async () => {
- const tool = createEditFileTool(workdir);
- const result = await tool.execute(
- { path: "/etc/passwd", oldString: "a", newString: "b" },
- stubCtx(),
- );
-
- expect(result.isError).toBe(true);
- expect(result.content).toContain("outside the working directory");
- });
-
- it("handles symlink escape attempt", async () => {
- const outsideDir = await mkdtemp(join(tmpdir(), "outside-"));
- const outsideFile = join(outsideDir, "secret.txt");
- await writeFile(outsideFile, "secret data", "utf8");
-
- const symlinkPath = join(workdir, "link.txt");
- const { symlink } = await import("node:fs/promises");
- await symlink(outsideFile, symlinkPath);
-
- const tool = createEditFileTool(workdir);
- const result = await tool.execute(
- { path: "link.txt", oldString: "secret", newString: "leaked" },
- stubCtx(),
- );
-
- expect(result.isError).toBe(true);
- expect(result.content).toContain("outside the working directory");
-
- await rm(outsideDir, { recursive: true, force: true });
- });
-
it("reads file under ctx.cwd when set", async () => {
const ctxDir = await mkdtemp(join(tmpdir(), "ctx-cwd-test-"));
try {