From: Hannes Magnusson Date: Wed, 14 Nov 2007 14:42:25 +0000 (+0000) Subject: Fixed bug#43293 (Multiple segfaults in getopt()) X-Git-Tag: RELEASE_1_3_1~646 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=35ba8020cd02879d3e6b546388cd27ff895e3c81;p=php Fixed bug#43293 (Multiple segfaults in getopt()) --- diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c index 2df99395aa..1688d44642 100644 --- a/ext/standard/basic_functions.c +++ b/ext/standard/basic_functions.c @@ -4552,11 +4552,11 @@ PHP_FUNCTION(getopt) /* Get argv from the global symbol table. We calculate argc ourselves * in order to be on the safe side, even though it is also available * from the symbol table. */ - if (zend_hash_find(HASH_OF(PG(http_globals)[TRACK_VARS_SERVER]), "argv", sizeof("argv"), (void **) &args) != FAILURE || - zend_hash_find(&EG(symbol_table), "argv", sizeof("argv"), (void **) &args) != FAILURE + if ((zend_hash_find(HASH_OF(PG(http_globals)[TRACK_VARS_SERVER]), "argv", sizeof("argv"), (void **) &args) != FAILURE || + zend_hash_find(&EG(symbol_table), "argv", sizeof("argv"), (void **) &args) != FAILURE) && Z_TYPE_PP(args) == IS_ARRAY ) { int pos = 0; - zval **arg; + zval **entry; argc = zend_hash_num_elements(Z_ARRVAL_PP(args)); @@ -4568,8 +4568,22 @@ PHP_FUNCTION(getopt) zend_hash_internal_pointer_reset(Z_ARRVAL_PP(args)); /* Iterate over the hash to construct the argv array. */ - while (zend_hash_get_current_data(Z_ARRVAL_PP(args), (void **)&arg) == SUCCESS) { - argv[pos++] = estrdup(Z_STRVAL_PP(arg)); + while (zend_hash_get_current_data(Z_ARRVAL_PP(args), (void **)&entry) == SUCCESS) { + zval arg, *arg_ptr = *entry; + + if (Z_TYPE_PP(entry) != IS_STRING) { + arg = **entry; + zval_copy_ctor(&arg); + convert_to_string(&arg); + arg_ptr = &arg; + } + + argv[pos++] = estrdup(Z_STRVAL_P(arg_ptr)); + + if (arg_ptr != *entry) { + zval_dtor(&arg); + } + zend_hash_move_forward(Z_ARRVAL_PP(args)); } @@ -4585,7 +4599,7 @@ PHP_FUNCTION(getopt) if (p_longopts) { int count; - zval **arg; + zval **entry; count = zend_hash_num_elements(Z_ARRVAL_P(p_longopts)); @@ -4605,9 +4619,18 @@ PHP_FUNCTION(getopt) zend_hash_internal_pointer_reset(Z_ARRVAL_P(p_longopts)); /* Iterate over the hash to construct the argv array. */ - while (zend_hash_get_current_data(Z_ARRVAL_P(p_longopts), (void **)&arg) == SUCCESS) { + while (zend_hash_get_current_data(Z_ARRVAL_P(p_longopts), (void **)&entry) == SUCCESS) { + zval arg, *arg_ptr = *entry; + + if (Z_TYPE_PP(entry) != IS_STRING) { + arg = **entry; + zval_copy_ctor(&arg); + convert_to_string(&arg); + arg_ptr = &arg; + } + opts->need_param = 0; - opts->opt_name = estrdup(Z_STRVAL_PP(arg)); + opts->opt_name = estrdup(Z_STRVAL_P(arg_ptr)); len = strlen(opts->opt_name); if ((len > 0) && (opts->opt_name[len - 1] == ':')) { opts->need_param++; @@ -4619,6 +4642,11 @@ PHP_FUNCTION(getopt) } opts->opt_char = 0; opts++; + + if (arg_ptr != *entry) { + zval_dtor(&arg); + } + zend_hash_move_forward(Z_ARRVAL_P(p_longopts)); } } else { diff --git a/ext/standard/tests/general_functions/bug43293_1.phpt b/ext/standard/tests/general_functions/bug43293_1.phpt new file mode 100644 index 0000000000..b4be252337 --- /dev/null +++ b/ext/standard/tests/general_functions/bug43293_1.phpt @@ -0,0 +1,25 @@ +--TEST-- +Bug#43293 (Multiple segfaults in getopt()) +--INI-- +register_argc_argv=Off +--FILE-- + +--EXPECT-- +array(0) { +} +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +bool(false) + diff --git a/ext/standard/tests/general_functions/bug43293_2.phpt b/ext/standard/tests/general_functions/bug43293_2.phpt new file mode 100644 index 0000000000..a91beebac6 --- /dev/null +++ b/ext/standard/tests/general_functions/bug43293_2.phpt @@ -0,0 +1,13 @@ +--TEST-- +Bug#43293 (Multiple segfaults in getopt()) +--INI-- +register_argc_argv=Off +--FILE-- + +--EXPECT-- +array(0) { +} + diff --git a/ext/standard/tests/general_functions/bug43293_3.phpt b/ext/standard/tests/general_functions/bug43293_3.phpt new file mode 100644 index 0000000000..6c4d6ec30d --- /dev/null +++ b/ext/standard/tests/general_functions/bug43293_3.phpt @@ -0,0 +1,30 @@ +--TEST-- +Bug#43293 (Multiple segfaults in getopt()) +--ARGS-- +-f --f +--INI-- +register_argc_argv=On +--FILE-- + +--EXPECT-- +array(1) { + ["f"]=> + array(2) { + [0]=> + bool(false) + [1]=> + bool(false) + } +} +array(3) { + [0]=> + bool(true) + [1]=> + bool(false) + [2]=> + string(1) "f" +} +