bjori Wed Nov 14 14:55:44 2007 UTC Modified files: /php-src/ext/standard basic_functions.c /php-src/ext/standard/tests/general_functions bug43293_1.phpt bug43293_2.phpt bug43293_3.phpt Log: MFB5.3: Fixed bug#43293 (Multiple segfaults in getopt()) http://cvs.php.net/viewvc.cgi/php-src/ext/standard/basic_functions.c?r1=1.881&r2=1.882&diff_format=u Index: php-src/ext/standard/basic_functions.c diff -u php-src/ext/standard/basic_functions.c:1.881 php-src/ext/standard/basic_functions.c:1.882 --- php-src/ext/standard/basic_functions.c:1.881 Fri Nov 2 10:57:56 2007 +++ php-src/ext/standard/basic_functions.c Wed Nov 14 14:55:44 2007 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: basic_functions.c,v 1.881 2007/11/02 10:57:56 jani Exp $ */ +/* $Id: basic_functions.c,v 1.882 2007/11/14 14:55:44 bjori Exp $ */ #include "php.h" #include "php_streams.h" @@ -4516,11 +4516,11 @@ /* 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_ascii_hash_find(HASH_OF(PG(http_globals)[TRACK_VARS_SERVER]), "argv", sizeof("argv"), (void **) &args) != FAILURE || - zend_ascii_hash_find(&EG(symbol_table), "argv", sizeof("argv"), (void **) &args) != FAILURE + if ((zend_ascii_hash_find(HASH_OF(PG(http_globals)[TRACK_VARS_SERVER]), "argv", sizeof("argv"), (void **) &args) != FAILURE || + zend_ascii_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)); @@ -4532,8 +4532,22 @@ 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)); } @@ -4549,7 +4563,7 @@ if (p_longopts) { int count; - zval **arg; + zval **entry; count = zend_hash_num_elements(Z_ARRVAL_P(p_longopts)); @@ -4569,9 +4583,18 @@ 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++; @@ -4583,6 +4606,11 @@ } opts->opt_char = 0; opts++; + + if (arg_ptr != *entry) { + zval_dtor(&arg); + } + zend_hash_move_forward(Z_ARRVAL_P(p_longopts)); } } else { http://cvs.php.net/viewvc.cgi/php-src/ext/standard/tests/general_functions/bug43293_1.phpt?r1=1.1&r2=1.2&diff_format=u Index: php-src/ext/standard/tests/general_functions/bug43293_1.phpt diff -u /dev/null php-src/ext/standard/tests/general_functions/bug43293_1.phpt:1.2 --- /dev/null Wed Nov 14 14:55:44 2007 +++ php-src/ext/standard/tests/general_functions/bug43293_1.phpt Wed Nov 14 14:55:44 2007 @@ -0,0 +1,25 @@ +--TEST-- +Bug#43293 (Multiple segfaults in getopt()) +--INI-- +register_argc_argv=Off +--FILE-- +<?php +$argv = array(1, 2, 3); +var_dump(getopt("abcd")); +var_dump($argv); +$argv = null; +var_dump(getopt("abcd")); +?> +--EXPECT-- +array(0) { +} +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +bool(false) + http://cvs.php.net/viewvc.cgi/php-src/ext/standard/tests/general_functions/bug43293_2.phpt?r1=1.1&r2=1.2&diff_format=u Index: php-src/ext/standard/tests/general_functions/bug43293_2.phpt diff -u /dev/null php-src/ext/standard/tests/general_functions/bug43293_2.phpt:1.2 --- /dev/null Wed Nov 14 14:55:44 2007 +++ php-src/ext/standard/tests/general_functions/bug43293_2.phpt Wed Nov 14 14:55:44 2007 @@ -0,0 +1,13 @@ +--TEST-- +Bug#43293 (Multiple segfaults in getopt()) +--INI-- +register_argc_argv=Off +--FILE-- +<?php +$argv = array(true, false); +var_dump(getopt("abcd")); +?> +--EXPECT-- +array(0) { +} + http://cvs.php.net/viewvc.cgi/php-src/ext/standard/tests/general_functions/bug43293_3.phpt?r1=1.1&r2=1.2&diff_format=u Index: php-src/ext/standard/tests/general_functions/bug43293_3.phpt diff -u /dev/null php-src/ext/standard/tests/general_functions/bug43293_3.phpt:1.2 --- /dev/null Wed Nov 14 14:55:44 2007 +++ php-src/ext/standard/tests/general_functions/bug43293_3.phpt Wed Nov 14 14:55:44 2007 @@ -0,0 +1,48 @@ +--TEST-- +Bug#43293 (Multiple segfaults in getopt()) +--ARGS-- +-f --f +--INI-- +register_argc_argv=On +--FILE-- +<?php +$args = array(true, false, "f"); +var_dump(getopt("f", $args), $args); +?> +--EXPECT-- +array(1) { + ["f"]=> + array(2) { + [0]=> + bool(false) + [1]=> + bool(false) + } +} +array(3) { + [0]=> + bool(true) + [1]=> + bool(false) + [2]=> + string(1) "f" +} +--UEXPECT-- +array(1) { + ["f"]=> + array(2) { + [0]=> + bool(false) + [1]=> + bool(false) + } +} +array(3) { + [0]=> + bool(true) + [1]=> + bool(false) + [2]=> + unicode(1) "f" +} +
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php