@@ -22,6 +22,9 @@ use bear::intercept::tcp::ReporterOnTcp;
2222use bear:: intercept:: Reporter ;
2323use bear:: intercept:: KEY_DESTINATION ;
2424use bear:: intercept:: { Event , Execution , ProcessId } ;
25+ use std:: ffi:: OsStr ;
26+ #[ cfg( target_os = "windows" ) ]
27+ use std:: ffi:: OsStr ;
2528use std:: path:: { Path , PathBuf } ;
2629
2730/// Implementation of the wrapper process.
@@ -85,8 +88,7 @@ fn next_in_path(target: &Path) -> Result<PathBuf> {
8588
8689 path. split ( ':' )
8790 . map ( |dir| Path :: new ( dir) . join ( target) )
88- // FIXME: check if it is executable
89- . filter ( |path| path. is_file ( ) )
91+ . filter ( |path| is_executable_file ( path) )
9092 . find ( |path| {
9193 // We need to compare it with the real path of the candidate executable to avoid
9294 // calling the same executable again.
@@ -127,3 +129,34 @@ fn into_execution(path_buf: &Path) -> Result<Execution> {
127129 environment : std:: env:: vars ( ) . collect ( ) ,
128130 } )
129131}
132+
133+ /// Checks if the given path is an executable file.
134+ fn is_executable_file ( path : & Path ) -> bool {
135+ if !path. is_file ( ) {
136+ return false ;
137+ }
138+
139+ #[ cfg( target_os = "windows" ) ]
140+ {
141+ path. extension ( )
142+ . map ( |ext| EXECUTABLE_EXTENSIONS . contains ( & ext) )
143+ . unwrap_or ( false )
144+ }
145+
146+ #[ cfg( not( target_os = "windows" ) ) ]
147+ {
148+ use std:: os:: unix:: fs:: PermissionsExt ;
149+ std:: fs:: metadata ( path)
150+ . map ( |metadata| metadata. permissions ( ) . mode ( ) & 0o100 != 0 )
151+ . unwrap_or ( false )
152+ }
153+ }
154+
155+ #[ cfg( target_os = "windows" ) ]
156+ const EXECUTABLE_EXTENSIONS : & [ & OsStr ] = & [
157+ OsStr :: new ( "exe" ) ,
158+ OsStr :: new ( "com" ) ,
159+ OsStr :: new ( "bat" ) ,
160+ OsStr :: new ( "cmd" ) ,
161+ OsStr :: new ( "ps1" ) ,
162+ ] ;
0 commit comments