when a shell tool call invokes apply_patch, resolve relative paths against workdir, if specified (#556)
Previously, we were ignoring the `workdir` field in an `ExecInput` when running it through `canAutoApprove()`. For ordinary `exec()` calls, that was sufficient, but for `apply_patch`, we need the `workdir` to resolve relative paths in the `apply_patch` argument so that we can check them in `isPathConstrainedTowritablePaths()`. Likewise, we also need the workdir when running `execApplyPatch()` because the paths need to be resolved again. Ideally, the `ApplyPatchCommand` returned by `canAutoApprove()` would not be a simple `patch: string`, but the parsed patch with all of the paths resolved, in which case `execApplyPatch()` could expect absolute paths and would not need `workdir`.
This commit is contained in:
@@ -10,6 +10,7 @@ import { formatCommandForDisplay } from "../../format-command.js";
|
||||
import fs from "fs";
|
||||
import os from "os";
|
||||
import { parse } from "shell-quote";
|
||||
import { resolvePathAgainstWorkdir } from "src/approvals.js";
|
||||
|
||||
const DEFAULT_TIMEOUT_MS = 10_000; // 10 seconds
|
||||
|
||||
@@ -60,16 +61,20 @@ export function exec(
|
||||
return execForSandbox(cmd, opts, writableRoots, abortSignal);
|
||||
}
|
||||
|
||||
export function execApplyPatch(patchText: string): ExecResult {
|
||||
export function execApplyPatch(
|
||||
patchText: string,
|
||||
workdir: string | undefined,
|
||||
): ExecResult {
|
||||
// This is a temporary measure to understand what are the common base commands
|
||||
// until we start persisting and uploading rollouts
|
||||
|
||||
try {
|
||||
const result = process_patch(
|
||||
patchText,
|
||||
(p) => fs.readFileSync(p, "utf8"),
|
||||
(p, c) => fs.writeFileSync(p, c, "utf8"),
|
||||
(p) => fs.unlinkSync(p),
|
||||
(p) => fs.readFileSync(resolvePathAgainstWorkdir(p, workdir), "utf8"),
|
||||
(p, c) =>
|
||||
fs.writeFileSync(resolvePathAgainstWorkdir(p, workdir), c, "utf8"),
|
||||
(p) => fs.unlinkSync(resolvePathAgainstWorkdir(p, workdir)),
|
||||
);
|
||||
return {
|
||||
stdout: result,
|
||||
|
||||
Reference in New Issue
Block a user