@@ -474,48 +474,39 @@ static void append_win_escaped_arg(smart_string *str, char *arg, BOOL is_cmd_arg
474
474
smart_string_appendc (str , '"' );
475
475
}
476
476
477
- static BOOL stricmp_end (const char * suffix , const char * str ) {
478
- size_t suffix_len = strlen (suffix );
479
- size_t str_len = strlen (str );
477
+ static BOOL is_executed_by_cmd (const char * prog_name , size_t prog_name_length )
478
+ {
479
+ size_t out_len ;
480
+ WCHAR long_name [MAX_PATH ];
481
+ WCHAR full_name [MAX_PATH ];
482
+ LPWSTR file_part = NULL ;
480
483
481
- if (suffix_len > str_len ) {
482
- return -1 ; /* Suffix is longer than string, cannot match. */
483
- }
484
+ wchar_t * prog_name_wide = php_win32_cp_conv_any_to_w (prog_name , prog_name_length , & out_len );
484
485
485
- /* Compare the end of the string with the suffix, ignoring case. */
486
- return _stricmp (str + (str_len - suffix_len ), suffix );
487
- }
486
+ if (GetLongPathNameW (prog_name_wide , long_name , MAX_PATH ) == 0 ) {
487
+ /* This can fail for example with ERROR_FILE_NOT_FOUND (short path resolution only works for existing files)
488
+ * in which case we'll pass the path verbatim to the FullPath transformation. */
489
+ lstrcpynW (long_name , prog_name_wide , MAX_PATH );
490
+ }
488
491
489
- static BOOL is_executed_by_cmd (const char * prog_name )
490
- {
491
- /* If program name is cmd.exe, then return true. */
492
- if (_stricmp ("cmd.exe" , prog_name ) == 0 || _stricmp ("cmd" , prog_name ) == 0
493
- || stricmp_end ("\\cmd.exe" , prog_name ) == 0 || stricmp_end ("\\cmd" , prog_name ) == 0 ) {
494
- return 1 ;
495
- }
492
+ free (prog_name_wide );
493
+ prog_name_wide = NULL ;
496
494
497
- /* Find the last occurrence of the directory separator (backslash or forward slash). */
498
- char * last_separator = strrchr (prog_name , '\\' );
499
- char * last_separator_fwd = strrchr (prog_name , '/' );
500
- if (last_separator_fwd && (!last_separator || last_separator < last_separator_fwd )) {
501
- last_separator = last_separator_fwd ;
495
+ if (GetFullPathNameW (long_name , MAX_PATH , full_name , & file_part ) == 0 || file_part == NULL ) {
496
+ return 0 ;
502
497
}
503
498
504
- /* Find the last dot in the filename after the last directory separator. */
505
- char * extension = NULL ;
506
- if (last_separator != NULL ) {
507
- extension = strrchr (last_separator , '.' );
499
+ BOOL uses_cmd = 0 ;
500
+ if (_wcsicmp (file_part , L"cmd.exe" ) == 0 || _wcsicmp (file_part , L"cmd" ) == 0 ) {
501
+ uses_cmd = 1 ;
508
502
} else {
509
- extension = strrchr (prog_name , '.' );
510
- }
511
-
512
- if (extension == NULL || extension == prog_name ) {
513
- /* No file extension found, it is not batch file. */
514
- return 0 ;
503
+ const WCHAR * extension_dot = wcsrchr (file_part , L'.' );
504
+ if (extension_dot && (_wcsicmp (extension_dot , L".bat" ) == 0 || _wcsicmp (extension_dot , L".cmd" ) == 0 )) {
505
+ uses_cmd = 1 ;
506
+ }
515
507
}
516
508
517
- /* Check if the file extension is ".bat" or ".cmd" which is always executed by cmd.exe. */
518
- return (_stricmp (extension , ".bat" ) == 0 || _stricmp (extension , ".cmd" ) == 0 ) ? 1 : 0 ;
509
+ return uses_cmd ;
519
510
}
520
511
521
512
static char * create_win_command_from_args (HashTable * args ) {
@@ -533,7 +524,7 @@ static char *create_win_command_from_args(HashTable *args) {
533
524
}
534
525
535
526
if (is_prog_name ) {
536
- is_cmd_execution = is_executed_by_cmd (ZSTR_VAL (arg_str ));
527
+ is_cmd_execution = is_executed_by_cmd (ZSTR_VAL (arg_str ), ZSTR_LEN ( arg_str ) );
537
528
} else {
538
529
smart_string_appendc (& str , ' ' );
539
530
}
0 commit comments