summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2019-04-08 11:11:58 +0200
committerNikita Popov <nikita.ppv@gmail.com>2019-04-08 11:11:58 +0200
commiteea61cda7df1466a1f40a17c21b65901c1c68ce0 (patch)
tree647ab53dd10481db538e5e67c182b671319d4623
parentd1d692abe71b04177747758237249253b175b8c2 (diff)
downloadphp-git-eea61cda7df1466a1f40a17c21b65901c1c68ce0.tar.gz
Fixed bug #77844
We should probably return an integer result from the operation in typed mode, right now the result is always a string.
-rw-r--r--NEWS2
-rw-r--r--Zend/zend_ini_parser.y34
-rw-r--r--ext/standard/tests/general_functions/bug77844.phpt19
3 files changed, 39 insertions, 16 deletions
diff --git a/NEWS b/NEWS
index d355778344..ed3f73aeac 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 768486cba4..a0ceb2c74e 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 0000000000..a8b6bf3d0d
--- /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--
+<?php
+
+$ini = <<<INI
+val1=3.7&2
+val2=2&3.7
+INI;
+var_dump(parse_ini_string($ini, true, INI_SCANNER_TYPED));
+
+?>
+--EXPECT--
+array(2) {
+ ["val1"]=>
+ string(1) "2"
+ ["val2"]=>
+ string(1) "2"
+}