fix(sandbox): anchor fs-bridge mkdirp
This commit is contained in:
@@ -135,10 +135,12 @@ async function expectMkdirpAllowsExistingDirectory(params?: { forceBoundaryIoFal
|
||||
|
||||
await expect(bridge.mkdirp({ filePath: "memory/kemik" })).resolves.toBeUndefined();
|
||||
|
||||
const mkdirCall = findCallByScriptFragment('mkdir -p -- "$1"');
|
||||
const mkdirCall = findCallByScriptFragment('mkdir -p -- "$2"');
|
||||
expect(mkdirCall).toBeDefined();
|
||||
const mkdirPath = mkdirCall ? getDockerPathArg(mkdirCall[0]) : "";
|
||||
expect(mkdirPath).toBe("/workspace/memory/kemik");
|
||||
const mkdirParent = mkdirCall ? getDockerArg(mkdirCall[0], 1) : "";
|
||||
const mkdirBase = mkdirCall ? getDockerArg(mkdirCall[0], 2) : "";
|
||||
expect(mkdirParent).toBe("/workspace/memory");
|
||||
expect(mkdirBase).toBe("kemik");
|
||||
});
|
||||
}
|
||||
|
||||
@@ -250,6 +252,24 @@ describe("sandbox fs bridge shell compatibility", () => {
|
||||
expect(scripts.some((script) => script.includes('mv -f -- "$1" "$2"'))).toBe(true);
|
||||
});
|
||||
|
||||
it("anchors mkdirp operations on canonical parent + basename", async () => {
|
||||
const bridge = createSandboxFsBridge({ sandbox: createSandbox() });
|
||||
|
||||
await bridge.mkdirp({ filePath: "nested/leaf" });
|
||||
|
||||
const mkdirCall = findCallByScriptFragment('mkdir -p -- "$2"');
|
||||
expect(mkdirCall).toBeDefined();
|
||||
const args = mkdirCall?.[0] ?? [];
|
||||
expect(getDockerArg(args, 1)).toBe("/workspace/nested");
|
||||
expect(getDockerArg(args, 2)).toBe("leaf");
|
||||
expect(args).not.toContain("/workspace/nested/leaf");
|
||||
|
||||
const canonicalCalls = findCallsByScriptFragment('readlink -f -- "$cursor"');
|
||||
expect(
|
||||
canonicalCalls.some(([callArgs]) => getDockerArg(callArgs, 1) === "/workspace/nested"),
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
it("anchors remove operations on canonical parent + basename", async () => {
|
||||
const bridge = createSandboxFsBridge({ sandbox: createSandbox() });
|
||||
|
||||
@@ -329,7 +349,8 @@ describe("sandbox fs bridge shell compatibility", () => {
|
||||
await expect(bridge.mkdirp({ filePath: "memory/kemik" })).rejects.toThrow(
|
||||
/cannot create directories/i,
|
||||
);
|
||||
expect(mockedExecDockerRaw).not.toHaveBeenCalled();
|
||||
const scripts = getScriptsFromCalls();
|
||||
expect(scripts.some((script) => script.includes('mkdir -p -- "$2"'))).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -155,6 +155,7 @@ class SandboxFsBridgeImpl implements SandboxFsBridge {
|
||||
async mkdirp(params: { filePath: string; cwd?: string; signal?: AbortSignal }): Promise<void> {
|
||||
const target = this.resolveResolvedPath(params);
|
||||
this.ensureWriteAccess(target, "create directories");
|
||||
const anchoredTarget = await this.resolveAnchoredSandboxEntry(target);
|
||||
await this.runCheckedCommand({
|
||||
checks: [
|
||||
{
|
||||
@@ -166,8 +167,8 @@ class SandboxFsBridgeImpl implements SandboxFsBridge {
|
||||
},
|
||||
},
|
||||
],
|
||||
script: 'set -eu; mkdir -p -- "$1"',
|
||||
args: [target.containerPath],
|
||||
script: 'set -eu\ncd -- "$1"\nmkdir -p -- "$2"',
|
||||
args: [anchoredTarget.canonicalParentPath, anchoredTarget.basename],
|
||||
signal: params.signal,
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user