mirror of
https://github.com/openai/codex.git
synced 2026-11-13 21:30:47 +00:00
Add filesystem-free classification of intercepted patch commands (#57573)
## What changed Add `MaybeApplyPatch::intercepts_command` to identify commands intercepted by exec without reading patch target files. Recognize explicit patch invocations, malformed patch bodies in those invocations, and implicit raw patches. Share implicit-patch detection with verified parsing, preserving its rejection of implicit invocations. ## Testing Add a unit test covering explicit, implicit, and malformed patches, plus an unrelated `echo apply_patch` command, without a filesystem. GitOrigin-RevId: 0bc9f63ca049094a2b17689f4f5585798792fe02
This commit is contained in:
@@ -107,6 +107,27 @@ fn extract_apply_patch_from_shell(
|
||||
}
|
||||
}
|
||||
|
||||
fn is_implicit_patch(argv: &[String], cwd: &PathUri) -> bool {
|
||||
let body = match argv {
|
||||
[body] => Some(body.as_str()),
|
||||
_ => parse_shell_script(argv, cwd).map(|(_, script)| script),
|
||||
};
|
||||
body.is_some_and(|body| parse_patch(body).is_ok())
|
||||
}
|
||||
|
||||
impl MaybeApplyPatch {
|
||||
/// Whether exec intercepts this command, without reading any patch target files.
|
||||
pub fn intercepts_command(argv: &[String], cwd: &PathUri) -> bool {
|
||||
if is_implicit_patch(argv, cwd) {
|
||||
return true;
|
||||
}
|
||||
match maybe_parse_apply_patch(argv, cwd) {
|
||||
Self::Body(_) | Self::PatchParseError(_) => true,
|
||||
Self::ShellParseError(_) | Self::NotApplyPatch => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: make private once we remove tests in lib.rs
|
||||
/// `cwd` supplies the path convention used to interpret the shell executable in `argv`.
|
||||
pub fn maybe_parse_apply_patch(argv: &[String], cwd: &PathUri) -> MaybeApplyPatch {
|
||||
@@ -144,16 +165,7 @@ pub async fn maybe_parse_apply_patch_verified(
|
||||
fs: &dyn ExecutorFileSystem,
|
||||
sandbox: Option<&codex_exec_server::FileSystemSandboxContext>,
|
||||
) -> MaybeApplyPatchVerified {
|
||||
// Detect a raw patch body passed directly as the command or as the body of a shell
|
||||
// script. In these cases, report an explicit error rather than applying the patch.
|
||||
if let [body] = argv
|
||||
&& parse_patch(body).is_ok()
|
||||
{
|
||||
return MaybeApplyPatchVerified::CorrectnessError(ApplyPatchError::ImplicitInvocation);
|
||||
}
|
||||
if let Some((_, script)) = parse_shell_script(argv, cwd)
|
||||
&& parse_patch(script).is_ok()
|
||||
{
|
||||
if is_implicit_patch(argv, cwd) {
|
||||
return MaybeApplyPatchVerified::CorrectnessError(ApplyPatchError::ImplicitInvocation);
|
||||
}
|
||||
|
||||
@@ -504,6 +516,26 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_intercepted_commands_without_a_filesystem() {
|
||||
let cwd = PathUri::parse("file:///workspace").expect("valid POSIX test cwd");
|
||||
let patch = wrap_patch("*** Delete File: target");
|
||||
let explicit = format!("apply_patch <<'PATCH'\n{patch}\nPATCH");
|
||||
let malformed = "apply_patch <<'PATCH'\ninvalid patch\nPATCH";
|
||||
for (script, intercepted) in [
|
||||
(explicit.as_str(), true),
|
||||
(patch.as_str(), true),
|
||||
(malformed, true),
|
||||
("echo apply_patch", false),
|
||||
] {
|
||||
assert_eq!(
|
||||
MaybeApplyPatch::intercepts_command(&args_bash(script), &cwd),
|
||||
intercepted,
|
||||
"{script}"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_implicit_patch_single_arg_is_error() {
|
||||
let patch = "*** Begin Patch\n*** Add File: foo\n+hi\n*** End Patch".to_string();
|
||||
|
||||
Reference in New Issue
Block a user