diff options
| author | Dmitry Stogov <dmitry@zend.com> | 2016-11-18 16:17:52 +0300 |
|---|---|---|
| committer | Dmitry Stogov <dmitry@zend.com> | 2016-11-18 16:17:52 +0300 |
| commit | 97b65cc9c2b2c50d974622458719756eb8e62003 (patch) | |
| tree | 2816016318dd8682aea9d9d76c23e29efc77eb64 | |
| parent | 0c78fe4bb55a9d39afc79cbcbadb9a273f2ec2ef (diff) | |
| download | php-git-97b65cc9c2b2c50d974622458719756eb8e62003.tar.gz | |
Fixed memory leaks in parse_ini_file()
| -rw-r--r-- | Zend/zend_ini_parser.y | 26 | ||||
| -rw-r--r-- | Zend/zend_ini_scanner.l | 4 | ||||
| -rw-r--r-- | ext/standard/basic_functions.c | 13 |
3 files changed, 27 insertions, 16 deletions
diff --git a/Zend/zend_ini_parser.y b/Zend/zend_ini_parser.y index ae04d2b70c..5e38defb15 100644 --- a/Zend/zend_ini_parser.y +++ b/Zend/zend_ini_parser.y @@ -46,6 +46,8 @@ int ini_parse(void); #define YYFREE free #endif +#define ZEND_SYSTEM_INI CG(ini_parser_unbuffered_errors) + /* {{{ zend_ini_do_op() */ static void zend_ini_do_op(char type, zval *result, zval *op1, zval *op2) @@ -86,7 +88,7 @@ static void zend_ini_do_op(char type, zval *result, zval *op1, zval *op2) } str_len = zend_sprintf(str_result, "%d", i_result); - ZVAL_PSTRINGL(result, str_result, str_len); + ZVAL_NEW_STR(result, zend_string_init(str_result, str_len, ZEND_SYSTEM_INI)); } /* }}} */ @@ -94,7 +96,11 @@ static void zend_ini_do_op(char type, zval *result, zval *op1, zval *op2) */ static void zend_ini_init_string(zval *result) { - ZVAL_EMPTY_PSTRING(result); + if (ZEND_SYSTEM_INI) { + ZVAL_EMPTY_PSTRING(result); + } else { + ZVAL_EMPTY_STRING(result); + } } /* }}} */ @@ -107,7 +113,11 @@ static void zend_ini_add_string(zval *result, zval *op1, zval *op2) if (Z_TYPE_P(op1) != IS_STRING) { zend_string *str = zval_get_string(op1); /* ZEND_ASSERT(!Z_REFCOUNTED_P(op1)); */ - ZVAL_PSTRINGL(op1, ZSTR_VAL(str), ZSTR_LEN(str)); + if (ZEND_SYSTEM_INI) { + ZVAL_PSTRINGL(op1, ZSTR_VAL(str), ZSTR_LEN(str)); + } else { + ZVAL_STR(op1, str); + } zend_string_release(str); } op1_len = (int)Z_STRLEN_P(op1); @@ -117,7 +127,7 @@ static void zend_ini_add_string(zval *result, zval *op1, zval *op2) } length = op1_len + (int)Z_STRLEN_P(op2); - ZVAL_NEW_STR(result, zend_string_extend(Z_STR_P(op1), length, 1)); + ZVAL_NEW_STR(result, zend_string_extend(Z_STR_P(op1), length, ZEND_SYSTEM_INI)); memcpy(Z_STRVAL_P(result) + op1_len, Z_STRVAL_P(op2), Z_STRLEN_P(op2) + 1); } /* }}} */ @@ -140,7 +150,7 @@ static void zend_ini_get_constant(zval *result, zval *name) convert_to_string(&tmp); c = &tmp; } - ZVAL_PSTRINGL(result, Z_STRVAL_P(c), Z_STRLEN_P(c)); + ZVAL_NEW_STR(result, zend_string_init(Z_STRVAL_P(c), Z_STRLEN_P(c), ZEND_SYSTEM_INI)); if (c == &tmp) { zend_string_release(Z_STR(tmp)); } @@ -160,11 +170,11 @@ static void zend_ini_get_var(zval *result, zval *name) /* Fetch configuration option value */ if ((curval = zend_get_configuration_directive(Z_STR_P(name))) != NULL) { - ZVAL_PSTRINGL(result, Z_STRVAL_P(curval), Z_STRLEN_P(curval)); + ZVAL_NEW_STR(result, zend_string_init(Z_STRVAL_P(curval), Z_STRLEN_P(curval), ZEND_SYSTEM_INI)); /* ..or if not found, try ENV */ } else if ((envvar = zend_getenv(Z_STRVAL_P(name), Z_STRLEN_P(name))) != NULL || (envvar = getenv(Z_STRVAL_P(name))) != NULL) { - ZVAL_PSTRING(result, envvar); + ZVAL_NEW_STR(result, zend_string_init(envvar, strlen(envvar), ZEND_SYSTEM_INI)); } else { zend_ini_init_string(result); } @@ -282,6 +292,8 @@ ZEND_API int zend_parse_ini_string(char *str, zend_bool unbuffered_errors, int s %left '|' '&' '^' %right '~' '!' +%destructor { zval_ptr_dtor(&$$); } TC_RAW TC_CONSTANT TC_NUMBER TC_STRING TC_WHITESPACE TC_LABEL TC_OFFSET TC_VARNAME BOOL_TRUE BOOL_FALSE NULL_NULL + %% statement_list: diff --git a/Zend/zend_ini_scanner.l b/Zend/zend_ini_scanner.l index 0aeeca9168..06c58c9c36 100644 --- a/Zend/zend_ini_scanner.l +++ b/Zend/zend_ini_scanner.l @@ -110,6 +110,8 @@ ZEND_API ts_rsrc_id ini_scanner_globals_id; ZEND_API zend_ini_scanner_globals ini_scanner_globals; #endif +#define ZEND_SYSTEM_INI CG(ini_parser_unbuffered_errors) + /* Eat leading whitespace */ #define EAT_LEADING_WHITESPACE() \ while (yyleng) { \ @@ -137,7 +139,7 @@ ZEND_API zend_ini_scanner_globals ini_scanner_globals; #define EAT_TRAILING_WHITESPACE() EAT_TRAILING_WHITESPACE_EX('X') #define zend_ini_copy_value(retval, str, len) \ - ZVAL_NEW_STR(retval, zend_string_init(str, len, 1)) + ZVAL_NEW_STR(retval, zend_string_init(str, len, ZEND_SYSTEM_INI)) #define RETURN_TOKEN(type, str, len) { \ diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c index 09124fa025..caf46aa675 100644 --- a/ext/standard/basic_functions.c +++ b/ext/standard/basic_functions.c @@ -5796,8 +5796,6 @@ PHP_FUNCTION(move_uploaded_file) */ static void php_simple_ini_parser_cb(zval *arg1, zval *arg2, zval *arg3, int callback_type, zval *arr) { - zval element; - switch (callback_type) { case ZEND_INI_PARSER_ENTRY: @@ -5805,8 +5803,8 @@ static void php_simple_ini_parser_cb(zval *arg1, zval *arg2, zval *arg3, int cal /* bare string - nothing to do */ break; } - ZVAL_DUP(&element, arg2); - zend_symtable_update(Z_ARRVAL_P(arr), Z_STR_P(arg1), &element); + Z_TRY_ADDREF_P(arg2); + zend_symtable_update(Z_ARRVAL_P(arr), Z_STR_P(arg1), arg2); break; case ZEND_INI_PARSER_POP_ENTRY: @@ -5836,12 +5834,11 @@ static void php_simple_ini_parser_cb(zval *arg1, zval *arg2, zval *arg3, int cal array_init(find_hash); } - ZVAL_DUP(&element, arg2); if (!arg3 || (Z_TYPE_P(arg3) == IS_STRING && Z_STRLEN_P(arg3) == 0)) { - add_next_index_zval(find_hash, &element); + Z_TRY_ADDREF_P(arg2); + add_next_index_zval(find_hash, arg2); } else { - array_set_zval_key(Z_ARRVAL_P(find_hash), arg3, &element); - zval_ptr_dtor(&element); + array_set_zval_key(Z_ARRVAL_P(find_hash), arg3, arg2); } } break; |
