@@ -698,22 +698,77 @@ static void init_process_info(PROCESS_INFORMATION *pi)
698
698
memset (& pi , 0 , sizeof (pi ));
699
699
}
700
700
701
+ /* on success, returns length of *comspec, which then needs to be efree'd by caller */
702
+ static size_t find_comspec_nt (wchar_t * * comspec )
703
+ {
704
+ zend_string * path = NULL ;
705
+ wchar_t * pathw = NULL ;
706
+ wchar_t * bufp = NULL ;
707
+ DWORD buflen = MAX_PATH , len = 0 ;
708
+
709
+ path = php_getenv ("PATH" , 4 );
710
+ if (path == NULL ) {
711
+ goto out ;
712
+ }
713
+ pathw = php_win32_cp_any_to_w (ZSTR_VAL (path ));
714
+ if (pathw == NULL ) {
715
+ goto out ;
716
+ }
717
+ bufp = emalloc (buflen * sizeof (wchar_t ));
718
+ do {
719
+ /* the first call to SearchPathW() fails if the buffer is too small,
720
+ * what is unlikely but possible; to avoid an explicit second call to
721
+ * SeachPathW() and the error handling, we're looping */
722
+ len = SearchPathW (pathw , L"cmd.exe" , NULL , buflen , bufp , NULL );
723
+ if (len == 0 ) {
724
+ goto out ;
725
+ }
726
+ if (len < buflen ) {
727
+ break ;
728
+ }
729
+ buflen = len ;
730
+ bufp = erealloc (bufp , buflen * sizeof (wchar_t ));
731
+ } while (1 );
732
+ * comspec = bufp ;
733
+
734
+ out :
735
+ if (path != NULL ) {
736
+ zend_string_release (path );
737
+ }
738
+ if (pathw != NULL ) {
739
+ free (pathw );
740
+ }
741
+ if (bufp != NULL && bufp != * comspec ) {
742
+ efree (bufp );
743
+ }
744
+ return len ;
745
+ }
746
+
701
747
static zend_result convert_command_to_use_shell (wchar_t * * cmdw , size_t cmdw_len )
702
748
{
703
- size_t len = sizeof (COMSPEC_NT ) + sizeof (" /s /c " ) + cmdw_len + 3 ;
749
+ wchar_t * comspec ;
750
+ size_t len = find_comspec_nt (& comspec );
751
+ if (len == 0 ) {
752
+ php_error_docref (NULL , E_WARNING , "Command conversion failed" );
753
+ return FAILURE ;
754
+ }
755
+ len += sizeof (" /s /c " ) + cmdw_len + 3 ;
704
756
wchar_t * cmdw_shell = (wchar_t * )malloc (len * sizeof (wchar_t ));
705
757
706
758
if (cmdw_shell == NULL ) {
759
+ efree (comspec );
707
760
php_error_docref (NULL , E_WARNING , "Command conversion failed" );
708
761
return FAILURE ;
709
762
}
710
763
711
- if (_snwprintf (cmdw_shell , len , L"%hs /s /c \"%s\"" , COMSPEC_NT , * cmdw ) == -1 ) {
764
+ if (_snwprintf (cmdw_shell , len , L"%s /s /c \"%s\"" , comspec , * cmdw ) == -1 ) {
765
+ efree (comspec );
712
766
free (cmdw_shell );
713
767
php_error_docref (NULL , E_WARNING , "Command conversion failed" );
714
768
return FAILURE ;
715
769
}
716
770
771
+ efree (comspec );
717
772
free (* cmdw );
718
773
* cmdw = cmdw_shell ;
719
774
0 commit comments