@@ -674,6 +674,40 @@ static int dup_proc_descriptor(php_file_descriptor_t from, php_file_descriptor_t
674
674
return SUCCESS ;
675
675
}
676
676
677
+ static int redirect_proc_descriptor (struct php_proc_open_descriptor_item * desc , int target , struct php_proc_open_descriptor_item * descriptors , int ndesc , int nindex )
678
+ {
679
+ php_file_descriptor_t redirect_to = PHP_INVALID_FD ;
680
+
681
+ for (int i = 0 ; i < ndesc ; i ++ ) {
682
+ if (descriptors [i ].index == target ) {
683
+ redirect_to = descriptors [i ].childend ;
684
+ break ;
685
+ }
686
+ }
687
+
688
+ if (redirect_to == PHP_INVALID_FD ) { /* didn't find the index we wanted */
689
+ if (target < 0 || target > 2 ) {
690
+ php_error_docref (NULL , E_WARNING , "Redirection target %d not found" , target );
691
+ return FAILURE ;
692
+ }
693
+
694
+ /* Support referring to a stdin/stdout/stderr pipe adopted from the parent,
695
+ * which happens whenever an explicit override is not provided. */
696
+ #ifndef PHP_WIN32
697
+ redirect_to = target ;
698
+ #else
699
+ switch (target ) {
700
+ case 0 : redirect_to = GetStdHandle (STD_INPUT_HANDLE ); break ;
701
+ case 1 : redirect_to = GetStdHandle (STD_OUTPUT_HANDLE ); break ;
702
+ case 2 : redirect_to = GetStdHandle (STD_ERROR_HANDLE ); break ;
703
+ EMPTY_SWITCH_DEFAULT_CASE ()
704
+ }
705
+ #endif
706
+ }
707
+
708
+ return dup_proc_descriptor (redirect_to , & desc -> childend , nindex );
709
+ }
710
+
677
711
static int close_parent_ends_of_pipes_in_child (struct php_proc_open_descriptor_item * descriptors , int ndesc )
678
712
{
679
713
/* we are running in child process
@@ -875,8 +909,6 @@ PHP_FUNCTION(proc_open)
875
909
}
876
910
} else if (zend_string_equals_literal (ztype , "redirect" )) {
877
911
zval * ztarget = zend_hash_index_find_deref (Z_ARRVAL_P (descitem ), 1 );
878
- php_file_descriptor_t childend = -1 ;
879
-
880
912
if (!ztarget ) {
881
913
zend_value_error ("Missing redirection target" );
882
914
goto exit_fail ;
@@ -885,36 +917,7 @@ PHP_FUNCTION(proc_open)
885
917
zend_value_error ("Redirection target must be an integer" );
886
918
goto exit_fail ;
887
919
}
888
-
889
- for (i = 0 ; i < ndesc ; i ++ ) {
890
- if (descriptors [i ].index == Z_LVAL_P (ztarget )) {
891
- childend = descriptors [i ].childend ;
892
- break ;
893
- }
894
- }
895
-
896
- if (childend == -1 ) {
897
- if (Z_LVAL_P (ztarget ) < 0 || Z_LVAL_P (ztarget ) > 2 ) {
898
- php_error_docref (NULL , E_WARNING ,
899
- "Redirection target " ZEND_LONG_FMT " not found" , Z_LVAL_P (ztarget ));
900
- goto exit_fail ;
901
- }
902
-
903
- /* Support referring to a stdin/stdout/stderr pipe adopted from the parent,
904
- * which happens whenever an explicit override is not provided. */
905
- #ifndef PHP_WIN32
906
- childend = Z_LVAL_P (ztarget );
907
- #else
908
- switch (Z_LVAL_P (ztarget )) {
909
- case 0 : childend = GetStdHandle (STD_INPUT_HANDLE ); break ;
910
- case 1 : childend = GetStdHandle (STD_OUTPUT_HANDLE ); break ;
911
- case 2 : childend = GetStdHandle (STD_ERROR_HANDLE ); break ;
912
- EMPTY_SWITCH_DEFAULT_CASE ()
913
- }
914
- #endif
915
- }
916
-
917
- if (dup_proc_descriptor (childend , & descriptors [ndesc ].childend , nindex ) == FAILURE ) {
920
+ if (redirect_proc_descriptor (& descriptors [ndesc ], Z_LVAL_P (ztarget ), descriptors , ndesc , nindex ) == FAILURE ) {
918
921
goto exit_fail ;
919
922
}
920
923
} else if (zend_string_equals_literal (ztype , "null" )) {
0 commit comments