mirror of
https://github.com/php/php-src.git
synced 2026-04-12 02:23:18 +02:00
Fixed bug#43293 (Multiple segfaults in getopt())
This commit is contained in:
@@ -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 {
|
||||
|
||||
25
ext/standard/tests/general_functions/bug43293_1.phpt
Normal file
25
ext/standard/tests/general_functions/bug43293_1.phpt
Normal file
@@ -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)
|
||||
|
||||
13
ext/standard/tests/general_functions/bug43293_2.phpt
Normal file
13
ext/standard/tests/general_functions/bug43293_2.phpt
Normal file
@@ -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) {
|
||||
}
|
||||
|
||||
30
ext/standard/tests/general_functions/bug43293_3.phpt
Normal file
30
ext/standard/tests/general_functions/bug43293_3.phpt
Normal file
@@ -0,0 +1,30 @@
|
||||
--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"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user