@@ -569,17 +569,14 @@ static struct php_proc_open_descriptor_item* alloc_descriptor_array(zval *descri
569
569
return ecalloc (sizeof (struct php_proc_open_descriptor_item ), ndescriptors );
570
570
}
571
571
572
- static int get_string_parameter (zval * * dest , zval * array , int index , char * param_name )
572
+ static zend_string * get_string_parameter (zval * array , int index , char * param_name )
573
573
{
574
- if ((* dest = zend_hash_index_find (Z_ARRVAL_P (array ), index )) == NULL ) {
574
+ zval * array_item ;
575
+ if ((array_item = zend_hash_index_find (Z_ARRVAL_P (array ), index )) == NULL ) {
575
576
zend_value_error ("Missing %s" , param_name );
576
- return FAILURE ;
577
- }
578
- if (!try_convert_to_string (* dest )) {
579
- return FAILURE ;
577
+ return NULL ;
580
578
}
581
-
582
- return SUCCESS ;
579
+ return zval_try_get_string (array_item );
583
580
}
584
581
585
582
static int set_proc_descriptor_to_blackhole (struct php_proc_open_descriptor_item * desc )
@@ -602,7 +599,7 @@ static int set_proc_descriptor_to_blackhole(struct php_proc_open_descriptor_item
602
599
return SUCCESS ;
603
600
}
604
601
605
- static int set_proc_descriptor_to_pipe (struct php_proc_open_descriptor_item * desc , zval * zmode )
602
+ static int set_proc_descriptor_to_pipe (struct php_proc_open_descriptor_item * desc , zend_string * zmode )
606
603
{
607
604
php_file_descriptor_t newpipe [2 ];
608
605
@@ -613,7 +610,7 @@ static int set_proc_descriptor_to_pipe(struct php_proc_open_descriptor_item *des
613
610
614
611
desc -> is_pipe = 1 ;
615
612
616
- if (strncmp (Z_STRVAL_P (zmode ), "w" , 1 ) != 0 ) {
613
+ if (strncmp (ZSTR_VAL (zmode ), "w" , 1 ) != 0 ) {
617
614
desc -> parentend = newpipe [1 ];
618
615
desc -> childend = newpipe [0 ];
619
616
desc -> mode_flags = O_WRONLY ;
@@ -627,19 +624,19 @@ static int set_proc_descriptor_to_pipe(struct php_proc_open_descriptor_item *des
627
624
/* don't let the child inherit the parent side of the pipe */
628
625
desc -> parentend = dup_handle (desc -> parentend , FALSE, TRUE);
629
626
630
- if (Z_STRLEN_P (zmode ) >= 2 && Z_STRVAL_P (zmode )[1 ] == 'b' )
627
+ if (ZSTR_LEN (zmode ) >= 2 && ZSTR_VAL (zmode )[1 ] == 'b' )
631
628
desc -> mode_flags |= O_BINARY ;
632
629
#endif
633
630
634
631
return SUCCESS ;
635
632
}
636
633
637
- static int set_proc_descriptor_to_file (struct php_proc_open_descriptor_item * desc , zval * zfile , zval * zmode )
634
+ static int set_proc_descriptor_to_file (struct php_proc_open_descriptor_item * desc , zend_string * zfile , zend_string * zmode )
638
635
{
639
636
php_socket_t fd ;
640
637
641
638
/* try a wrapper */
642
- php_stream * stream = php_stream_open_wrapper (Z_STRVAL_P (zfile ), Z_STRVAL_P (zmode ),
639
+ php_stream * stream = php_stream_open_wrapper (ZSTR_VAL (zfile ), ZSTR_VAL (zmode ),
643
640
REPORT_ERRORS |STREAM_WILL_CAST , NULL );
644
641
if (stream == NULL ) {
645
642
return FAILURE ;
@@ -656,7 +653,7 @@ static int set_proc_descriptor_to_file(struct php_proc_open_descriptor_item *des
656
653
657
654
/* simulate the append mode by fseeking to the end of the file
658
655
this introduces a potential race-condition, but it is the best we can do, though */
659
- if (strchr (Z_STRVAL_P (zmode ), 'a' )) {
656
+ if (strchr (ZSTR_VAL (zmode ), 'a' )) {
660
657
SetFilePointer (desc -> childend , 0 , NULL , FILE_END );
661
658
}
662
659
#else
@@ -766,6 +763,13 @@ PHP_FUNCTION(proc_open)
766
763
#endif
767
764
php_process_id_t child ;
768
765
struct php_process_handle * proc ;
766
+
767
+ /* zend_strings which may be allocated while processing the descriptorspec
768
+ * we need to make sure that each one allocated is released once and only once */
769
+ zend_string * ztype = NULL , * zmode = NULL , * zfile = NULL ;
770
+ #define cleanup_zend_string (ptr ) do { zend_tmp_string_release(ptr); ptr = NULL; } while(0)
771
+ #define cleanup_zend_strings () cleanup_zend_string(ztype); cleanup_zend_string(zmode); cleanup_zend_string(zfile)
772
+
769
773
#if PHP_CAN_DO_PTS
770
774
php_file_descriptor_t dev_ptmx = -1 ; /* master */
771
775
php_file_descriptor_t slave_pty = -1 ;
@@ -825,8 +829,6 @@ PHP_FUNCTION(proc_open)
825
829
826
830
/* walk the descriptor spec and set up files/pipes */
827
831
ZEND_HASH_FOREACH_KEY_VAL (Z_ARRVAL_P (descriptorspec ), nindex , str_index , descitem ) {
828
- zval * ztype ;
829
-
830
832
if (str_index ) {
831
833
zend_argument_value_error (2 , "must be an integer indexed array" );
832
834
goto exit_fail ;
@@ -857,33 +859,28 @@ PHP_FUNCTION(proc_open)
857
859
} else if (Z_TYPE_P (descitem ) != IS_ARRAY ) {
858
860
zend_argument_value_error (2 , "must only contain arrays and File-Handles" );
859
861
goto exit_fail ;
860
- } else if (get_string_parameter ( & ztype , descitem , 0 , "handle qualifier" ) == FAILURE ) {
862
+ } else if (( ztype = get_string_parameter ( descitem , 0 , "handle qualifier" )) == NULL ) {
861
863
goto exit_fail ;
862
864
} else {
863
- if (strcmp (Z_STRVAL_P (ztype ), "pipe" ) == 0 ) {
864
- zval * zmode ;
865
-
866
- if (get_string_parameter (& zmode , descitem , 1 , "mode parameter for 'pipe'" ) == FAILURE ) {
865
+ if (zend_string_equals_literal (ztype , "pipe" )) {
866
+ if ((zmode = get_string_parameter (descitem , 1 , "mode parameter for 'pipe'" )) == NULL ) {
867
867
goto exit_fail ;
868
868
}
869
-
870
869
if (set_proc_descriptor_to_pipe (& descriptors [ndesc ], zmode ) == FAILURE ) {
871
870
goto exit_fail ;
872
871
}
873
- } else if (strcmp (Z_STRVAL_P (ztype ), "file" ) == 0 ) {
874
- zval * zfile , * zmode ;
875
-
876
- if (get_string_parameter (& zfile , descitem , 1 , "file name parameter for 'file'" ) == FAILURE ) {
872
+ } else if (zend_string_equals_literal (ztype , "file" )) {
873
+ if ((zfile = get_string_parameter (descitem , 1 , "file name parameter for 'file'" )) == NULL ) {
877
874
goto exit_fail ;
878
875
}
879
- if (get_string_parameter ( & zmode , descitem , 2 , "mode parameter for 'file'" ) == FAILURE ) {
876
+ if (( zmode = get_string_parameter ( descitem , 2 , "mode parameter for 'file'" )) == NULL ) {
880
877
goto exit_fail ;
881
878
}
882
879
883
880
if (set_proc_descriptor_to_file (& descriptors [ndesc ], zfile , zmode ) == FAILURE ) {
884
881
goto exit_fail ;
885
882
}
886
- } else if (strcmp ( Z_STRVAL_P ( ztype ) , "redirect" ) == 0 ) {
883
+ } else if (zend_string_equals_literal ( ztype , "redirect" )) {
887
884
zval * ztarget = zend_hash_index_find_deref (Z_ARRVAL_P (descitem ), 1 );
888
885
php_file_descriptor_t childend = -1 ;
889
886
@@ -927,11 +924,11 @@ PHP_FUNCTION(proc_open)
927
924
if (dup_proc_descriptor (childend , & descriptors [ndesc ].childend , nindex ) == FAILURE ) {
928
925
goto exit_fail ;
929
926
}
930
- } else if (strcmp ( Z_STRVAL_P ( ztype ) , "null" ) == 0 ) {
927
+ } else if (zend_string_equals_literal ( ztype , "null" )) {
931
928
if (set_proc_descriptor_to_blackhole (& descriptors [ndesc ]) == FAILURE ) {
932
929
goto exit_fail ;
933
930
}
934
- } else if (strcmp ( Z_STRVAL_P ( ztype ) , "pty" ) == 0 ) {
931
+ } else if (zend_string_equals_literal ( ztype , "pty" )) {
935
932
#if PHP_CAN_DO_PTS
936
933
if (dev_ptmx == -1 ) {
937
934
/* open things up */
@@ -958,9 +955,10 @@ PHP_FUNCTION(proc_open)
958
955
goto exit_fail ;
959
956
#endif
960
957
} else {
961
- php_error_docref (NULL , E_WARNING , "%s is not a valid descriptor spec/mode" , Z_STRVAL_P (ztype ));
958
+ php_error_docref (NULL , E_WARNING , "%s is not a valid descriptor spec/mode" , ZSTR_VAL (ztype ));
962
959
goto exit_fail ;
963
960
}
961
+ cleanup_zend_strings ();
964
962
}
965
963
ndesc ++ ;
966
964
} ZEND_HASH_FOREACH_END ();
@@ -1209,6 +1207,7 @@ PHP_FUNCTION(proc_open)
1209
1207
#else
1210
1208
efree_argv (argv );
1211
1209
#endif
1210
+ cleanup_zend_strings ();
1212
1211
#if PHP_CAN_DO_PTS
1213
1212
if (dev_ptmx >= 0 ) {
1214
1213
close (dev_ptmx );
0 commit comments