fix: add broad-cwd guard to resume path

claw --resume now enforces the same broad-cwd safety policy as claw prompt
and the interactive REPL. Running from /, $HOME, or other broad directories
blocks execution unless --allow-broad-cwd is passed.

Generated with https://github.com/Yeachan-Heo/gajae-code
Co-authored-by: Gajae Code <dev@gajae-code.com>
This commit is contained in:
bellman
2026-06-05 00:22:54 +09:00
parent 78c2a49ec8
commit 9f9b14a76d
2 changed files with 21 additions and 5 deletions

View File

@@ -1036,7 +1036,11 @@ fn run() -> Result<(), Box<dyn std::error::Error>> {
session_path,
commands,
output_format,
} => resume_session(&session_path, &commands, output_format),
allow_broad_cwd,
} => {
enforce_broad_cwd_policy(allow_broad_cwd, output_format)?;
resume_session(&session_path, &commands, output_format)
}
CliAction::Status {
model,
model_flag_raw,
@@ -1191,6 +1195,7 @@ enum CliAction {
session_path: PathBuf,
commands: Vec<String>,
output_format: CliOutputFormat,
allow_broad_cwd: bool,
},
Status {
model: String,
@@ -1818,10 +1823,10 @@ fn parse_args(args: &[String]) -> Result<CliAction, String> {
return action;
}
if rest.first().map(String::as_str) == Some("--resume") {
return parse_resume_args(&rest[1..], output_format);
return parse_resume_args(&rest[1..], output_format, allow_broad_cwd);
}
if rest.first().map(String::as_str) == Some("resume") {
return parse_resume_args(&rest[1..], output_format);
return parse_resume_args(&rest[1..], output_format, allow_broad_cwd);
}
// #696: `claw compact` is the bare name of the interactive `/compact`
// slash command, not a prompt. When extra args such as `--help` appear
@@ -3177,7 +3182,11 @@ fn parse_dump_manifests_args(
})
}
fn parse_resume_args(args: &[String], output_format: CliOutputFormat) -> Result<CliAction, String> {
fn parse_resume_args(
args: &[String],
output_format: CliOutputFormat,
allow_broad_cwd: bool,
) -> Result<CliAction, String> {
let (session_path, command_tokens): (PathBuf, &[String]) = match args.first() {
None => (PathBuf::from(LATEST_SESSION_REFERENCE), &[]),
Some(first) if looks_like_slash_command_token(first) => {
@@ -3221,6 +3230,7 @@ fn parse_resume_args(args: &[String], output_format: CliOutputFormat) -> Result<
session_path,
commands,
output_format,
allow_broad_cwd,
})
}
@@ -16307,6 +16317,7 @@ mod tests {
session_path: PathBuf::from("session.jsonl"),
commands: vec!["/compact".to_string()],
output_format: CliOutputFormat::Text,
allow_broad_cwd: false,
}
);
}
@@ -16319,6 +16330,7 @@ mod tests {
session_path: PathBuf::from("latest"),
commands: vec![],
output_format: CliOutputFormat::Text,
allow_broad_cwd: false,
}
);
assert_eq!(
@@ -16328,6 +16340,7 @@ mod tests {
session_path: PathBuf::from("latest"),
commands: vec!["/status".to_string()],
output_format: CliOutputFormat::Text,
allow_broad_cwd: false,
}
);
}
@@ -16351,6 +16364,7 @@ mod tests {
"/cost".to_string(),
],
output_format: CliOutputFormat::Text,
allow_broad_cwd: false,
}
);
}
@@ -16382,6 +16396,7 @@ mod tests {
"/clear --confirm".to_string(),
],
output_format: CliOutputFormat::Text,
allow_broad_cwd: false,
}
);
}
@@ -16401,6 +16416,7 @@ mod tests {
session_path: PathBuf::from("session.jsonl"),
commands: vec!["/export /tmp/notes.txt".to_string(), "/status".to_string()],
output_format: CliOutputFormat::Text,
allow_broad_cwd: false,
}
);
}