src / __tests__ / paths.test.ts
import { describe, it, expect } from "vitest";
import { resolveWithinRoot } from "../paths";
// Confinement is the only thing standing between write_file/apply_patch and
// arbitrary writes anywhere on disk. These pin both escape vectors shut.
const ROOT = "/Users/me/project";
describe("resolveWithinRoot — path confinement", () => {
it("resolves a relative path inside the root", () => {
expect(resolveWithinRoot(ROOT, "src/index.ts")).toBe(`${ROOT}/src/index.ts`);
});
it("allows an absolute path that lands inside the root", () => {
expect(resolveWithinRoot(ROOT, `${ROOT}/src/a.ts`)).toBe(`${ROOT}/src/a.ts`);
});
it("rejects an absolute path outside the root", () => {
expect(() => resolveWithinRoot(ROOT, "/etc/cron.d/evil")).toThrow(/escapes the project root/);
});
it("rejects `..` traversal", () => {
expect(() => resolveWithinRoot(ROOT, "../../../../etc/passwd")).toThrow(/escapes the project root/);
});
it("rejects a sibling dir that shares the root's prefix", () => {
// /Users/me/project-evil must NOT count as inside /Users/me/project.
expect(() => resolveWithinRoot(ROOT, "/Users/me/project-evil/x")).toThrow(/escapes the project root/);
});
it("allows a real filename that merely starts with dots", () => {
expect(resolveWithinRoot(ROOT, "..foo")).toBe(`${ROOT}/..foo`);
});
it("refuses when no root is configured (fail closed, never write unconfined)", () => {
expect(() => resolveWithinRoot("", "src/a.ts")).toThrow(/No project root/);
expect(() => resolveWithinRoot(" ", "src/a.ts")).toThrow(/No project root/);
});
});
src / __tests__ / paths.test.ts
import { describe, it, expect } from "vitest";
import { resolveWithinRoot } from "../paths";
// Confinement is the only thing standing between write_file/apply_patch and
// arbitrary writes anywhere on disk. These pin both escape vectors shut.
const ROOT = "/Users/me/project";
describe("resolveWithinRoot — path confinement", () => {
it("resolves a relative path inside the root", () => {
expect(resolveWithinRoot(ROOT, "src/index.ts")).toBe(`${ROOT}/src/index.ts`);
});
it("allows an absolute path that lands inside the root", () => {
expect(resolveWithinRoot(ROOT, `${ROOT}/src/a.ts`)).toBe(`${ROOT}/src/a.ts`);
});
it("rejects an absolute path outside the root", () => {
expect(() => resolveWithinRoot(ROOT, "/etc/cron.d/evil")).toThrow(/escapes the project root/);
});
it("rejects `..` traversal", () => {
expect(() => resolveWithinRoot(ROOT, "../../../../etc/passwd")).toThrow(/escapes the project root/);
});
it("rejects a sibling dir that shares the root's prefix", () => {
// /Users/me/project-evil must NOT count as inside /Users/me/project.
expect(() => resolveWithinRoot(ROOT, "/Users/me/project-evil/x")).toThrow(/escapes the project root/);
});
it("allows a real filename that merely starts with dots", () => {
expect(resolveWithinRoot(ROOT, "..foo")).toBe(`${ROOT}/..foo`);
});
it("refuses when no root is configured (fail closed, never write unconfined)", () => {
expect(() => resolveWithinRoot("", "src/a.ts")).toThrow(/No project root/);
expect(() => resolveWithinRoot(" ", "src/a.ts")).toThrow(/No project root/);
});
});