Skip to content

Commit 40ddf9d

Browse files
committed
Introduce get_command_from_array helper in proc_open.c
1 parent f0d56b6 commit 40ddf9d

File tree

1 file changed

+34
-21
lines changed

1 file changed

+34
-21
lines changed

ext/standard/proc_open.c

Lines changed: 34 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -531,6 +531,37 @@ static int convert_command_to_use_shell(wchar_t **cmdw, size_t cmdw_len)
531531
}
532532
#endif
533533

534+
static int get_command_from_array(zval *array, char ***argv, char **command, int num_elems, int is_persistent)
535+
{
536+
zval *arg_zv;
537+
int i = 0;
538+
539+
*argv = safe_emalloc(sizeof(char *), num_elems + 1, 0);
540+
541+
ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(array), arg_zv) {
542+
zend_string *arg_str = get_valid_arg_string(arg_zv, i + 1);
543+
if (!arg_str) {
544+
/* terminate argv with NULL so exit_fail code knows how many entries to free */
545+
(*argv)[i] = NULL;
546+
return FAILURE;
547+
}
548+
549+
if (i == 0) {
550+
*command = pestrdup(ZSTR_VAL(arg_str), is_persistent);
551+
}
552+
553+
(*argv)[i++] = estrdup(ZSTR_VAL(arg_str));
554+
zend_string_release(arg_str);
555+
} ZEND_HASH_FOREACH_END();
556+
557+
(*argv)[i] = NULL;
558+
559+
/* As the array is non-empty, we should have found a command. */
560+
ZEND_ASSERT(command);
561+
562+
return SUCCESS;
563+
}
564+
534565
static struct php_proc_open_descriptor_item* alloc_descriptor_array(zval *descriptorspec)
535566
{
536567
int ndescriptors = zend_hash_num_elements(Z_ARRVAL_P(descriptorspec));
@@ -756,7 +787,6 @@ PHP_FUNCTION(proc_open)
756787
memset(&env, 0, sizeof(env));
757788

758789
if (Z_TYPE_P(command_zv) == IS_ARRAY) {
759-
zval *arg_zv;
760790
uint32_t num_elems = zend_hash_num_elements(Z_ARRVAL_P(command_zv));
761791
if (num_elems == 0) {
762792
zend_argument_value_error(1, "must have at least one element");
@@ -770,26 +800,9 @@ PHP_FUNCTION(proc_open)
770800
RETURN_FALSE;
771801
}
772802
#else
773-
argv = safe_emalloc(sizeof(char *), num_elems + 1, 0);
774-
i = 0;
775-
ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(command_zv), arg_zv) {
776-
zend_string *arg_str = get_valid_arg_string(arg_zv, i + 1);
777-
if (!arg_str) {
778-
argv[i] = NULL;
779-
goto exit_fail;
780-
}
781-
782-
if (i == 0) {
783-
command = pestrdup(ZSTR_VAL(arg_str), is_persistent);
784-
}
785-
786-
argv[i++] = estrdup(ZSTR_VAL(arg_str));
787-
zend_string_release(arg_str);
788-
} ZEND_HASH_FOREACH_END();
789-
argv[i] = NULL;
790-
791-
/* As the array is non-empty, we should have found a command. */
792-
ZEND_ASSERT(command);
803+
if (get_command_from_array(command_zv, &argv, &command, num_elems, is_persistent) == FAILURE) {
804+
goto exit_fail;
805+
}
793806
#endif
794807
} else {
795808
convert_to_string(command_zv);

0 commit comments

Comments
 (0)