Skip to content

Commit 02c7cd2

Browse files
committed
Use zend_string for strings in proc_open
1 parent 7142bf8 commit 02c7cd2

File tree

1 file changed

+25
-21
lines changed

1 file changed

+25
-21
lines changed

ext/standard/proc_open.c

Lines changed: 25 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -571,13 +571,14 @@ static struct php_proc_open_descriptor_item* alloc_descriptor_array(zval *descri
571571
return descriptors;
572572
}
573573

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)
575575
{
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) {
577578
zend_value_error("Missing %s", param_name);
578579
return FAILURE;
579580
}
580-
if (!try_convert_to_string(*dest)) {
581+
if ((*dest = zval_try_get_string(array_item)) == NULL) {
581582
return FAILURE;
582583
}
583584

@@ -604,7 +605,7 @@ static int set_proc_descriptor_to_blackhole(struct php_proc_open_descriptor_item
604605
return SUCCESS;
605606
}
606607

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)
608609
{
609610
php_file_descriptor_t newpipe[2];
610611

@@ -615,7 +616,7 @@ static int set_proc_descriptor_to_pipe(struct php_proc_open_descriptor_item *des
615616

616617
desc->is_pipe = 1;
617618

618-
if (strncmp(Z_STRVAL_P(zmode), "w", 1) != 0) {
619+
if (strncmp(ZSTR_VAL(zmode), "w", 1) != 0) {
619620
desc->parentend = newpipe[1];
620621
desc->childend = newpipe[0];
621622
desc->mode_flags = O_WRONLY;
@@ -629,19 +630,19 @@ static int set_proc_descriptor_to_pipe(struct php_proc_open_descriptor_item *des
629630
/* don't let the child inherit the parent side of the pipe */
630631
desc->parentend = dup_handle(desc->parentend, FALSE, TRUE);
631632

632-
if (Z_STRLEN_P(zmode) >= 2 && Z_STRVAL_P(zmode)[1] == 'b')
633+
if (ZSTR_LEN(zmode) >= 2 && ZSTR_VAL(zmode)[1] == 'b')
633634
desc->mode_flags |= O_BINARY;
634635
#endif
635636

636637
return SUCCESS;
637638
}
638639

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)
640641
{
641642
php_socket_t fd;
642643

643644
/* 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),
645646
REPORT_ERRORS|STREAM_WILL_CAST, NULL);
646647

647648
/* force into an fd */
@@ -658,7 +659,7 @@ static int set_proc_descriptor_to_file(struct php_proc_open_descriptor_item *des
658659

659660
/* simulate the append mode by fseeking to the end of the file
660661
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')) {
662663
SetFilePointer(desc->childend, 0, NULL, FILE_END);
663664
}
664665
#else
@@ -768,6 +769,13 @@ PHP_FUNCTION(proc_open)
768769
#endif
769770
php_process_id_t child;
770771
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+
771779
#if PHP_CAN_DO_PTS
772780
php_file_descriptor_t dev_ptmx = -1; /* master */
773781
php_file_descriptor_t slave_pty = -1;
@@ -827,8 +835,6 @@ PHP_FUNCTION(proc_open)
827835

828836
/* walk the descriptor spec and set up files/pipes */
829837
ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(descriptorspec), nindex, str_index, descitem) {
830-
zval *ztype;
831-
832838
if (str_index) {
833839
zend_argument_value_error(2, "must be an integer indexed array");
834840
goto exit_fail;
@@ -862,19 +868,15 @@ PHP_FUNCTION(proc_open)
862868
} else if (get_string_parameter(&ztype, descitem, 0, "handle qualifier") == FAILURE) {
863869
goto exit_fail;
864870
} else {
865-
if (strcmp(Z_STRVAL_P(ztype), "pipe") == 0) {
866-
zval *zmode;
867-
871+
if (strcmp(ZSTR_VAL(ztype), "pipe") == 0) {
868872
if (get_string_parameter(&zmode, descitem, 1, "mode parameter for 'pipe'") == FAILURE) {
869873
goto exit_fail;
870874
}
871875

872876
if (set_proc_descriptor_to_pipe(&descriptors[ndesc], zmode) == FAILURE) {
873877
goto exit_fail;
874878
}
875-
} else if (strcmp(Z_STRVAL_P(ztype), "file") == 0) {
876-
zval *zfile, *zmode;
877-
879+
} else if (strcmp(ZSTR_VAL(ztype), "file") == 0) {
878880
if (get_string_parameter(&zfile, descitem, 1, "file name parameter for 'file'") == FAILURE) {
879881
goto exit_fail;
880882
}
@@ -885,7 +887,7 @@ PHP_FUNCTION(proc_open)
885887
if (set_proc_descriptor_to_file(&descriptors[ndesc], zfile, zmode) == FAILURE) {
886888
goto exit_fail;
887889
}
888-
} else if (strcmp(Z_STRVAL_P(ztype), "redirect") == 0) {
890+
} else if (strcmp(ZSTR_VAL(ztype), "redirect") == 0) {
889891
zval *ztarget = zend_hash_index_find_deref(Z_ARRVAL_P(descitem), 1);
890892
php_file_descriptor_t childend = -1;
891893

@@ -929,11 +931,11 @@ PHP_FUNCTION(proc_open)
929931
if (dup_proc_descriptor(childend, &descriptors[ndesc].childend, nindex) == FAILURE) {
930932
goto exit_fail;
931933
}
932-
} else if (strcmp(Z_STRVAL_P(ztype), "null") == 0) {
934+
} else if (strcmp(ZSTR_VAL(ztype), "null") == 0) {
933935
if (set_proc_descriptor_to_blackhole(&descriptors[ndesc]) == FAILURE) {
934936
goto exit_fail;
935937
}
936-
} else if (strcmp(Z_STRVAL_P(ztype), "pty") == 0) {
938+
} else if (strcmp(ZSTR_VAL(ztype), "pty") == 0) {
937939
#if PHP_CAN_DO_PTS
938940
if (dev_ptmx == -1) {
939941
/* open things up */
@@ -960,9 +962,10 @@ PHP_FUNCTION(proc_open)
960962
goto exit_fail;
961963
#endif
962964
} 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));
964966
goto exit_fail;
965967
}
968+
cleanup_zend_strings();
966969
}
967970
ndesc++;
968971
} ZEND_HASH_FOREACH_END();
@@ -1211,6 +1214,7 @@ PHP_FUNCTION(proc_open)
12111214
#else
12121215
efree_argv(argv);
12131216
#endif
1217+
cleanup_zend_strings();
12141218
#if PHP_CAN_DO_PTS
12151219
if (dev_ptmx >= 0) {
12161220
close(dev_ptmx);

0 commit comments

Comments
 (0)