diff --git a/NEWS b/NEWS index 78c25894391..b3730bbabcc 100644 --- a/NEWS +++ b/NEWS @@ -38,6 +38,8 @@ PHP NEWS - Standard: . Fixed bug #77793 (Segmentation fault in extract() when overwriting reference with itself). (Nikita) + . Fixed bug #77844 (Crash due to null pointer in parse_ini_string with + INI_SCANNER_TYPED). (Nikita) 04 Apr 2019, PHP 7.3.4 diff --git a/Zend/zend_ini_parser.y b/Zend/zend_ini_parser.y index ffc2203e8ff..a83976a2d67 100644 --- a/Zend/zend_ini_parser.y +++ b/Zend/zend_ini_parser.y @@ -46,6 +46,22 @@ int ini_parse(void); #define ZEND_SYSTEM_INI CG(ini_parser_unbuffered_errors) +static int get_int_val(zval *op) { + switch (Z_TYPE_P(op)) { + case IS_LONG: + return Z_LVAL_P(op); + case IS_DOUBLE: + return (int)Z_DVAL_P(op); + case IS_STRING: + { + int val = atoi(Z_STRVAL_P(op)); + zend_string_free(Z_STR_P(op)); + return val; + } + EMPTY_SWITCH_DEFAULT_CASE() + } +} + /* {{{ zend_ini_do_op() */ static void zend_ini_do_op(char type, zval *result, zval *op1, zval *op2) @@ -55,22 +71,8 @@ static void zend_ini_do_op(char type, zval *result, zval *op1, zval *op2) int str_len; char str_result[MAX_LENGTH_OF_LONG+1]; - if (IS_LONG == Z_TYPE_P(op1)) { - i_op1 = Z_LVAL_P(op1); - } else { - i_op1 = atoi(Z_STRVAL_P(op1)); - zend_string_free(Z_STR_P(op1)); - } - if (op2) { - if (IS_LONG == Z_TYPE_P(op2)) { - i_op2 = Z_LVAL_P(op2); - } else { - i_op2 = atoi(Z_STRVAL_P(op2)); - zend_string_free(Z_STR_P(op2)); - } - } else { - i_op2 = 0; - } + i_op1 = get_int_val(op1); + i_op2 = op2 ? get_int_val(op2) : 0; switch (type) { case '|': diff --git a/ext/standard/tests/general_functions/bug77844.phpt b/ext/standard/tests/general_functions/bug77844.phpt new file mode 100644 index 00000000000..a8b6bf3d0dd --- /dev/null +++ b/ext/standard/tests/general_functions/bug77844.phpt @@ -0,0 +1,19 @@ +--TEST-- +Bug #77844: Crash due to null pointer in parse_ini_string with INI_SCANNER_TYPED +--FILE-- + +--EXPECT-- +array(2) { + ["val1"]=> + string(1) "2" + ["val2"]=> + string(1) "2" +}