@@ -571,13 +571,14 @@ static struct php_proc_open_descriptor_item* alloc_descriptor_array(zval *descri
571
571
return descriptors ;
572
572
}
573
573
574
- static int get_string_parameter (zval * * dest , zval * array , int index , char * param_name )
574
+ static int get_string_parameter (zend_string * * dest , zval * array , int index , char * param_name )
575
575
{
576
- if ((* dest = zend_hash_index_find (Z_ARRVAL_P (array ), index )) == NULL ) {
576
+ zval * array_item ;
577
+ if ((array_item = zend_hash_index_find (Z_ARRVAL_P (array ), index )) == NULL ) {
577
578
zend_value_error ("Missing %s" , param_name );
578
579
return FAILURE ;
579
580
}
580
- if (! try_convert_to_string (* dest ) ) {
581
+ if ((* dest = zval_try_get_string ( array_item )) == NULL ) {
581
582
return FAILURE ;
582
583
}
583
584
@@ -604,7 +605,7 @@ static int set_proc_descriptor_to_blackhole(struct php_proc_open_descriptor_item
604
605
return SUCCESS ;
605
606
}
606
607
607
- static int set_proc_descriptor_to_pipe (struct php_proc_open_descriptor_item * desc , zval * zmode )
608
+ static int set_proc_descriptor_to_pipe (struct php_proc_open_descriptor_item * desc , zend_string * zmode )
608
609
{
609
610
php_file_descriptor_t newpipe [2 ];
610
611
@@ -615,7 +616,7 @@ static int set_proc_descriptor_to_pipe(struct php_proc_open_descriptor_item *des
615
616
616
617
desc -> is_pipe = 1 ;
617
618
618
- if (strncmp (Z_STRVAL_P (zmode ), "w" , 1 ) != 0 ) {
619
+ if (strncmp (ZSTR_VAL (zmode ), "w" , 1 ) != 0 ) {
619
620
desc -> parentend = newpipe [1 ];
620
621
desc -> childend = newpipe [0 ];
621
622
desc -> mode_flags = O_WRONLY ;
@@ -629,19 +630,19 @@ static int set_proc_descriptor_to_pipe(struct php_proc_open_descriptor_item *des
629
630
/* don't let the child inherit the parent side of the pipe */
630
631
desc -> parentend = dup_handle (desc -> parentend , FALSE, TRUE);
631
632
632
- if (Z_STRLEN_P (zmode ) >= 2 && Z_STRVAL_P (zmode )[1 ] == 'b' )
633
+ if (ZSTR_LEN (zmode ) >= 2 && ZSTR_VAL (zmode )[1 ] == 'b' )
633
634
desc -> mode_flags |= O_BINARY ;
634
635
#endif
635
636
636
637
return SUCCESS ;
637
638
}
638
639
639
- static int set_proc_descriptor_to_file (struct php_proc_open_descriptor_item * desc , zval * zfile , zval * zmode )
640
+ static int set_proc_descriptor_to_file (struct php_proc_open_descriptor_item * desc , zend_string * zfile , zend_string * zmode )
640
641
{
641
642
php_socket_t fd ;
642
643
643
644
/* try a wrapper */
644
- php_stream * stream = php_stream_open_wrapper (Z_STRVAL_P (zfile ), Z_STRVAL_P (zmode ),
645
+ php_stream * stream = php_stream_open_wrapper (ZSTR_VAL (zfile ), ZSTR_VAL (zmode ),
645
646
REPORT_ERRORS |STREAM_WILL_CAST , NULL );
646
647
647
648
/* force into an fd */
@@ -658,7 +659,7 @@ static int set_proc_descriptor_to_file(struct php_proc_open_descriptor_item *des
658
659
659
660
/* simulate the append mode by fseeking to the end of the file
660
661
this introduces a potential race-condition, but it is the best we can do, though */
661
- if (strchr (Z_STRVAL_P (zmode ), 'a' )) {
662
+ if (strchr (ZSTR_VAL (zmode ), 'a' )) {
662
663
SetFilePointer (desc -> childend , 0 , NULL , FILE_END );
663
664
}
664
665
#else
@@ -768,6 +769,13 @@ PHP_FUNCTION(proc_open)
768
769
#endif
769
770
php_process_id_t child ;
770
771
struct php_process_handle * proc ;
772
+
773
+ /* zend_strings which may be allocated while processing the descriptorspec
774
+ * we need to make sure that each one allocated is released once and only once */
775
+ zend_string * ztype = NULL , * zmode = NULL , * zfile = NULL ;
776
+ #define cleanup_zend_string (ptr ) do { if (ptr != NULL) { zend_string_release(ptr); ptr = NULL; } } while(0)
777
+ #define cleanup_zend_strings () cleanup_zend_string(ztype); cleanup_zend_string(zmode); cleanup_zend_string(zfile)
778
+
771
779
#if PHP_CAN_DO_PTS
772
780
php_file_descriptor_t dev_ptmx = -1 ; /* master */
773
781
php_file_descriptor_t slave_pty = -1 ;
@@ -827,8 +835,6 @@ PHP_FUNCTION(proc_open)
827
835
828
836
/* walk the descriptor spec and set up files/pipes */
829
837
ZEND_HASH_FOREACH_KEY_VAL (Z_ARRVAL_P (descriptorspec ), nindex , str_index , descitem ) {
830
- zval * ztype ;
831
-
832
838
if (str_index ) {
833
839
zend_argument_value_error (2 , "must be an integer indexed array" );
834
840
goto exit_fail ;
@@ -862,19 +868,15 @@ PHP_FUNCTION(proc_open)
862
868
} else if (get_string_parameter (& ztype , descitem , 0 , "handle qualifier" ) == FAILURE ) {
863
869
goto exit_fail ;
864
870
} else {
865
- if (strcmp (Z_STRVAL_P (ztype ), "pipe" ) == 0 ) {
866
- zval * zmode ;
867
-
871
+ if (strcmp (ZSTR_VAL (ztype ), "pipe" ) == 0 ) {
868
872
if (get_string_parameter (& zmode , descitem , 1 , "mode parameter for 'pipe'" ) == FAILURE ) {
869
873
goto exit_fail ;
870
874
}
871
875
872
876
if (set_proc_descriptor_to_pipe (& descriptors [ndesc ], zmode ) == FAILURE ) {
873
877
goto exit_fail ;
874
878
}
875
- } else if (strcmp (Z_STRVAL_P (ztype ), "file" ) == 0 ) {
876
- zval * zfile , * zmode ;
877
-
879
+ } else if (strcmp (ZSTR_VAL (ztype ), "file" ) == 0 ) {
878
880
if (get_string_parameter (& zfile , descitem , 1 , "file name parameter for 'file'" ) == FAILURE ) {
879
881
goto exit_fail ;
880
882
}
@@ -885,7 +887,7 @@ PHP_FUNCTION(proc_open)
885
887
if (set_proc_descriptor_to_file (& descriptors [ndesc ], zfile , zmode ) == FAILURE ) {
886
888
goto exit_fail ;
887
889
}
888
- } else if (strcmp (Z_STRVAL_P (ztype ), "redirect" ) == 0 ) {
890
+ } else if (strcmp (ZSTR_VAL (ztype ), "redirect" ) == 0 ) {
889
891
zval * ztarget = zend_hash_index_find_deref (Z_ARRVAL_P (descitem ), 1 );
890
892
php_file_descriptor_t childend = -1 ;
891
893
@@ -929,11 +931,11 @@ PHP_FUNCTION(proc_open)
929
931
if (dup_proc_descriptor (childend , & descriptors [ndesc ].childend , nindex ) == FAILURE ) {
930
932
goto exit_fail ;
931
933
}
932
- } else if (strcmp (Z_STRVAL_P (ztype ), "null" ) == 0 ) {
934
+ } else if (strcmp (ZSTR_VAL (ztype ), "null" ) == 0 ) {
933
935
if (set_proc_descriptor_to_blackhole (& descriptors [ndesc ]) == FAILURE ) {
934
936
goto exit_fail ;
935
937
}
936
- } else if (strcmp (Z_STRVAL_P (ztype ), "pty" ) == 0 ) {
938
+ } else if (strcmp (ZSTR_VAL (ztype ), "pty" ) == 0 ) {
937
939
#if PHP_CAN_DO_PTS
938
940
if (dev_ptmx == -1 ) {
939
941
/* open things up */
@@ -960,9 +962,10 @@ PHP_FUNCTION(proc_open)
960
962
goto exit_fail ;
961
963
#endif
962
964
} else {
963
- php_error_docref (NULL , E_WARNING , "%s is not a valid descriptor spec/mode" , Z_STRVAL_P (ztype ));
965
+ php_error_docref (NULL , E_WARNING , "%s is not a valid descriptor spec/mode" , ZSTR_VAL (ztype ));
964
966
goto exit_fail ;
965
967
}
968
+ cleanup_zend_strings ();
966
969
}
967
970
ndesc ++ ;
968
971
} ZEND_HASH_FOREACH_END ();
@@ -1211,6 +1214,7 @@ PHP_FUNCTION(proc_open)
1211
1214
#else
1212
1215
efree_argv (argv );
1213
1216
#endif
1217
+ cleanup_zend_strings ();
1214
1218
#if PHP_CAN_DO_PTS
1215
1219
if (dev_ptmx >= 0 ) {
1216
1220
close (dev_ptmx );
0 commit comments