From eea61cda7df1466a1f40a17c21b65901c1c68ce0 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Mon, 8 Apr 2019 11:11:58 +0200 Subject: [PATCH] Fixed bug #77844 We should probably return an integer result from the operation in typed mode, right now the result is always a string. --- NEWS | 2 ++ Zend/zend_ini_parser.y | 34 ++++++++++--------- .../tests/general_functions/bug77844.phpt | 19 +++++++++++ 3 files changed, 39 insertions(+), 16 deletions(-) create mode 100644 ext/standard/tests/general_functions/bug77844.phpt diff --git a/NEWS b/NEWS index d3557783446..ed3f73aeacc 100644 --- a/NEWS +++ b/NEWS @@ -30,6 +30,8 @@ PHP NEWS - Standard: . Fixed bug #77680 (recursive mkdir on ftp stream wrapper is incorrect). (Vlad Temian) + . Fixed bug #77844 (Crash due to null pointer in parse_ini_string with + INI_SCANNER_TYPED). (Nikita) 04 Apr 2019, PHP 7.2.17 diff --git a/Zend/zend_ini_parser.y b/Zend/zend_ini_parser.y index 768486cba4e..a0ceb2c74ea 100644 --- a/Zend/zend_ini_parser.y +++ b/Zend/zend_ini_parser.y @@ -48,6 +48,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) @@ -57,22 +73,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" +}