@@ -69,12 +69,20 @@ impl ExecuteBash {
6969
7070 // Check if each command in the pipe chain starts with a safe command
7171 for cmd_args in all_commands {
72- if let Some ( cmd) = cmd_args. first ( ) {
73- if !READONLY_COMMANDS . contains ( & cmd. as_str ( ) ) {
72+ match cmd_args. first ( ) {
73+ // Special casing for `find` so that we support most cases while safeguarding
74+ // against unwanted mutations
75+ Some ( cmd)
76+ if cmd == "find"
77+ && cmd_args
78+ . iter ( )
79+ . any ( |arg| arg. contains ( "-exec" ) || arg. contains ( "-delete" ) ) =>
80+ {
7481 return true ;
75- }
76- } else {
77- return true ;
82+ } ,
83+ Some ( cmd) if !READONLY_COMMANDS . contains ( & cmd. as_str ( ) ) => return true ,
84+ None => return true ,
85+ _ => ( ) ,
7886 }
7987 }
8088
@@ -289,6 +297,11 @@ mod tests {
289297 ( "find . -name '*.rs' | rm" , true ) ,
290298 ( "ls -la | grep .git | rm -rf" , true ) ,
291299 ( "echo hello | sudo rm -rf /" , true ) ,
300+ // `find` command arguments
301+ ( "find important-dir/ -exec rm {} \\ ;" , true ) ,
302+ ( "find . -name '*.c' -execdir gcc -o '{}.out' '{}' \\ ;" , true ) ,
303+ ( "find important-dir/ -delete" , true ) ,
304+ ( "find important-dir/ -name '*.txt'" , false ) ,
292305 ] ;
293306 for ( cmd, expected) in cmds {
294307 let tool = serde_json:: from_value :: < ExecuteBash > ( serde_json:: json!( {
0 commit comments