Skip to content

Commit 3c99c0b

Browse files
committed
Use zend_string for strings in proc_open
1 parent a15dc8d commit 3c99c0b

File tree

1 file changed

+30
-31
lines changed

1 file changed

+30
-31
lines changed

ext/standard/proc_open.c

Lines changed: 30 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -569,17 +569,14 @@ static struct php_proc_open_descriptor_item* alloc_descriptor_array(zval *descri
569569
return ecalloc(sizeof(struct php_proc_open_descriptor_item), ndescriptors);
570570
}
571571

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)
573573
{
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) {
575576
zend_value_error("Missing %s", param_name);
576-
return FAILURE;
577-
}
578-
if (!try_convert_to_string(*dest)) {
579-
return FAILURE;
577+
return NULL;
580578
}
581-
582-
return SUCCESS;
579+
return zval_try_get_string(array_item);
583580
}
584581

585582
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
602599
return SUCCESS;
603600
}
604601

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)
606603
{
607604
php_file_descriptor_t newpipe[2];
608605

@@ -613,7 +610,7 @@ static int set_proc_descriptor_to_pipe(struct php_proc_open_descriptor_item *des
613610

614611
desc->is_pipe = 1;
615612

616-
if (strncmp(Z_STRVAL_P(zmode), "w", 1) != 0) {
613+
if (strncmp(ZSTR_VAL(zmode), "w", 1) != 0) {
617614
desc->parentend = newpipe[1];
618615
desc->childend = newpipe[0];
619616
desc->mode_flags = O_WRONLY;
@@ -627,19 +624,19 @@ static int set_proc_descriptor_to_pipe(struct php_proc_open_descriptor_item *des
627624
/* don't let the child inherit the parent side of the pipe */
628625
desc->parentend = dup_handle(desc->parentend, FALSE, TRUE);
629626

630-
if (Z_STRLEN_P(zmode) >= 2 && Z_STRVAL_P(zmode)[1] == 'b')
627+
if (ZSTR_LEN(zmode) >= 2 && ZSTR_VAL(zmode)[1] == 'b')
631628
desc->mode_flags |= O_BINARY;
632629
#endif
633630

634631
return SUCCESS;
635632
}
636633

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)
638635
{
639636
php_socket_t fd;
640637

641638
/* 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),
643640
REPORT_ERRORS|STREAM_WILL_CAST, NULL);
644641
if (stream == NULL) {
645642
return FAILURE;
@@ -656,7 +653,7 @@ static int set_proc_descriptor_to_file(struct php_proc_open_descriptor_item *des
656653

657654
/* simulate the append mode by fseeking to the end of the file
658655
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')) {
660657
SetFilePointer(desc->childend, 0, NULL, FILE_END);
661658
}
662659
#else
@@ -766,6 +763,13 @@ PHP_FUNCTION(proc_open)
766763
#endif
767764
php_process_id_t child;
768765
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+
769773
#if PHP_CAN_DO_PTS
770774
php_file_descriptor_t dev_ptmx = -1; /* master */
771775
php_file_descriptor_t slave_pty = -1;
@@ -825,8 +829,6 @@ PHP_FUNCTION(proc_open)
825829

826830
/* walk the descriptor spec and set up files/pipes */
827831
ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(descriptorspec), nindex, str_index, descitem) {
828-
zval *ztype;
829-
830832
if (str_index) {
831833
zend_argument_value_error(2, "must be an integer indexed array");
832834
goto exit_fail;
@@ -857,33 +859,28 @@ PHP_FUNCTION(proc_open)
857859
} else if (Z_TYPE_P(descitem) != IS_ARRAY) {
858860
zend_argument_value_error(2, "must only contain arrays and File-Handles");
859861
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) {
861863
goto exit_fail;
862864
} 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) {
867867
goto exit_fail;
868868
}
869-
870869
if (set_proc_descriptor_to_pipe(&descriptors[ndesc], zmode) == FAILURE) {
871870
goto exit_fail;
872871
}
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) {
877874
goto exit_fail;
878875
}
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) {
880877
goto exit_fail;
881878
}
882879

883880
if (set_proc_descriptor_to_file(&descriptors[ndesc], zfile, zmode) == FAILURE) {
884881
goto exit_fail;
885882
}
886-
} else if (strcmp(Z_STRVAL_P(ztype), "redirect") == 0) {
883+
} else if (zend_string_equals_literal(ztype, "redirect")) {
887884
zval *ztarget = zend_hash_index_find_deref(Z_ARRVAL_P(descitem), 1);
888885
php_file_descriptor_t childend = -1;
889886

@@ -927,11 +924,11 @@ PHP_FUNCTION(proc_open)
927924
if (dup_proc_descriptor(childend, &descriptors[ndesc].childend, nindex) == FAILURE) {
928925
goto exit_fail;
929926
}
930-
} else if (strcmp(Z_STRVAL_P(ztype), "null") == 0) {
927+
} else if (zend_string_equals_literal(ztype, "null")) {
931928
if (set_proc_descriptor_to_blackhole(&descriptors[ndesc]) == FAILURE) {
932929
goto exit_fail;
933930
}
934-
} else if (strcmp(Z_STRVAL_P(ztype), "pty") == 0) {
931+
} else if (zend_string_equals_literal(ztype, "pty")) {
935932
#if PHP_CAN_DO_PTS
936933
if (dev_ptmx == -1) {
937934
/* open things up */
@@ -958,9 +955,10 @@ PHP_FUNCTION(proc_open)
958955
goto exit_fail;
959956
#endif
960957
} 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));
962959
goto exit_fail;
963960
}
961+
cleanup_zend_strings();
964962
}
965963
ndesc++;
966964
} ZEND_HASH_FOREACH_END();
@@ -1209,6 +1207,7 @@ PHP_FUNCTION(proc_open)
12091207
#else
12101208
efree_argv(argv);
12111209
#endif
1210+
cleanup_zend_strings();
12121211
#if PHP_CAN_DO_PTS
12131212
if (dev_ptmx >= 0) {
12141213
close(dev_ptmx);

0 commit comments

Comments
 (0)