@@ -698,22 +698,77 @@ static void init_process_info(PROCESS_INFORMATION *pi)
698698	memset (& pi , 0 , sizeof (pi ));
699699}
700700
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+ 
701747static  zend_result  convert_command_to_use_shell (wchar_t  * * cmdw , size_t  cmdw_len )
702748{
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 ;
704756	wchar_t  * cmdw_shell  =  (wchar_t  * )malloc (len  *  sizeof (wchar_t ));
705757
706758	if  (cmdw_shell  ==  NULL ) {
759+ 		efree (comspec );
707760		php_error_docref (NULL , E_WARNING , "Command conversion failed" );
708761		return  FAILURE ;
709762	}
710763
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 );
712766		free (cmdw_shell );
713767		php_error_docref (NULL , E_WARNING , "Command conversion failed" );
714768		return  FAILURE ;
715769	}
716770
771+ 	efree (comspec );
717772	free (* cmdw );
718773	* cmdw  =  cmdw_shell ;
719774
0 commit comments