53 lines
2.1 KiB
TypeScript
53 lines
2.1 KiB
TypeScript
import { describe, expect, test } from "bun:test"
|
|
import path from "path"
|
|
import { isWithinRoot, resolveWritableRoots, isPathWritable } from "../../src/sandbox/path"
|
|
|
|
describe("sandbox.path", () => {
|
|
test("strict: session dir allowed, sibling dir denied", () => {
|
|
const session = path.resolve("/workspace/project/session-a")
|
|
const sibling = path.resolve("/workspace/project/session-b/out.txt")
|
|
const roots = resolveWritableRoots({ sandbox_mode: "strict" }, session)
|
|
|
|
expect(isPathWritable(path.join(session, "a.txt"), roots)).toBe(true)
|
|
expect(isPathWritable(sibling, roots)).toBe(false)
|
|
})
|
|
|
|
test("isWithinRoot rejects parent escape", () => {
|
|
const root = path.resolve("C:/workspace/session")
|
|
const outside = path.resolve("C:/workspace/other/file.txt")
|
|
expect(isWithinRoot(outside, root)).toBe(false)
|
|
})
|
|
|
|
test("permissive yields empty roots (no gate)", () => {
|
|
const roots = resolveWritableRoots({ sandbox_mode: "permissive" }, "/any")
|
|
expect(roots).toEqual([])
|
|
expect(isPathWritable("/anywhere", roots)).toBe(true)
|
|
})
|
|
|
|
test("strict: no system temp in writable roots", () => {
|
|
const session = path.resolve("/workspace/project/session-a")
|
|
const roots = resolveWritableRoots({ sandbox_mode: "strict" }, session)
|
|
const temp = process.env.TEMP || process.env.TMP || "/tmp"
|
|
if (temp) {
|
|
expect(isPathWritable(path.join(path.resolve(temp), "escape.txt"), roots)).toBe(false)
|
|
}
|
|
})
|
|
|
|
test("strict ignores configured writable_roots (session cwd only)", () => {
|
|
const session = path.resolve("/workspace/project/session-a")
|
|
const projectRoot = path.resolve("/workspace/project")
|
|
const sibling = path.resolve("/workspace/project/session-b/out.txt")
|
|
const roots = resolveWritableRoots(
|
|
{
|
|
sandbox_mode: "strict",
|
|
writable_roots: [projectRoot],
|
|
},
|
|
session,
|
|
)
|
|
|
|
expect(isPathWritable(path.join(session, "a.txt"), roots)).toBe(true)
|
|
expect(isPathWritable(path.join(projectRoot, "shared.txt"), roots)).toBe(false)
|
|
expect(isPathWritable(sibling, roots)).toBe(false)
|
|
})
|
|
})
|