@@ -269,11 +269,11 @@ impl Command {
269269 None
270270 } ;
271271 let program = resolve_exe ( & self . program , || env:: var_os ( "PATH" ) , child_paths) ?;
272- let is_batch_file = program
273- . extension ( )
274- . map ( |ext| ext . eq_ignore_ascii_case ( "cmd" ) || ext . eq_ignore_ascii_case ( "bat" ) )
275- . unwrap_or ( false ) ;
276- let program = path :: maybe_verbatim ( & program ) ? ;
272+ // Case insensitive "ends_with" of UTF-16 encoded ".bat" or ".cmd"
273+ let is_batch_file = matches ! (
274+ program . len ( ) . checked_sub ( 5 ) . and_then ( |i| program . get ( i.. ) ) ,
275+ Some ( [ 46 , 98 | 66 , 97 | 65 , 116 | 84 , 0 ] | [ 46 , 99 | 67 , 109 | 77 , 100 | 68 , 0 ] )
276+ ) ;
277277 let mut cmd_str =
278278 make_command_line ( & program, & self . args , self . force_quotes_enabled , is_batch_file) ?;
279279 cmd_str. push ( 0 ) ; // add null terminator
@@ -370,7 +370,7 @@ fn resolve_exe<'a>(
370370 exe_path : & ' a OsStr ,
371371 parent_paths : impl FnOnce ( ) -> Option < OsString > ,
372372 child_paths : Option < & OsStr > ,
373- ) -> io:: Result < PathBuf > {
373+ ) -> io:: Result < Vec < u16 > > {
374374 // Early return if there is no filename.
375375 if exe_path. is_empty ( ) || path:: has_trailing_slash ( exe_path) {
376376 return Err ( io:: const_io_error!(
@@ -392,19 +392,19 @@ fn resolve_exe<'a>(
392392 if has_exe_suffix {
393393 // The application name is a path to a `.exe` file.
394394 // Let `CreateProcessW` figure out if it exists or not.
395- return Ok ( exe_path . into ( ) ) ;
395+ return path :: maybe_verbatim ( Path :: new ( exe_path ) ) ;
396396 }
397397 let mut path = PathBuf :: from ( exe_path) ;
398398
399399 // Append `.exe` if not already there.
400400 path = path:: append_suffix ( path, EXE_SUFFIX . as_ref ( ) ) ;
401- if program_exists ( & path) {
401+ if let Some ( path ) = program_exists ( & path) {
402402 return Ok ( path) ;
403403 } else {
404404 // It's ok to use `set_extension` here because the intent is to
405405 // remove the extension that was just added.
406406 path. set_extension ( "" ) ;
407- return Ok ( path) ;
407+ return path :: maybe_verbatim ( & path) ;
408408 }
409409 } else {
410410 ensure_no_nuls ( exe_path) ?;
@@ -419,7 +419,7 @@ fn resolve_exe<'a>(
419419 if !has_extension {
420420 path. set_extension ( EXE_EXTENSION ) ;
421421 }
422- if program_exists ( & path) { Some ( path ) } else { None }
422+ program_exists ( & path)
423423 } ) ;
424424 if let Some ( path) = result {
425425 return Ok ( path) ;
@@ -435,10 +435,10 @@ fn search_paths<Paths, Exists>(
435435 parent_paths : Paths ,
436436 child_paths : Option < & OsStr > ,
437437 mut exists : Exists ,
438- ) -> Option < PathBuf >
438+ ) -> Option < Vec < u16 > >
439439where
440440 Paths : FnOnce ( ) -> Option < OsString > ,
441- Exists : FnMut ( PathBuf ) -> Option < PathBuf > ,
441+ Exists : FnMut ( PathBuf ) -> Option < Vec < u16 > > ,
442442{
443443 // 1. Child paths
444444 // This is for consistency with Rust's historic behaviour.
@@ -490,17 +490,18 @@ where
490490}
491491
492492/// Check if a file exists without following symlinks.
493- fn program_exists ( path : & Path ) -> bool {
493+ fn program_exists ( path : & Path ) -> Option < Vec < u16 > > {
494494 unsafe {
495- to_u16s ( path)
496- . map ( |path| {
497- // Getting attributes using `GetFileAttributesW` does not follow symlinks
498- // and it will almost always be successful if the link exists.
499- // There are some exceptions for special system files (e.g. the pagefile)
500- // but these are not executable.
501- c:: GetFileAttributesW ( path. as_ptr ( ) ) != c:: INVALID_FILE_ATTRIBUTES
502- } )
503- . unwrap_or ( false )
495+ let path = path:: maybe_verbatim ( path) . ok ( ) ?;
496+ // Getting attributes using `GetFileAttributesW` does not follow symlinks
497+ // and it will almost always be successful if the link exists.
498+ // There are some exceptions for special system files (e.g. the pagefile)
499+ // but these are not executable.
500+ if c:: GetFileAttributesW ( path. as_ptr ( ) ) == c:: INVALID_FILE_ATTRIBUTES {
501+ None
502+ } else {
503+ Some ( path)
504+ }
504505 }
505506}
506507
0 commit comments