Skip to content

Commit 97b65cc

Browse files
committed
Fixed memory leaks in parse_ini_file()
1 parent 0c78fe4 commit 97b65cc

File tree

3 files changed

+27
-16
lines changed

3 files changed

+27
-16
lines changed

Zend/zend_ini_parser.y

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ int ini_parse(void);
4646
#define YYFREE free
4747
#endif
4848

49+
#define ZEND_SYSTEM_INI CG(ini_parser_unbuffered_errors)
50+
4951
/* {{{ zend_ini_do_op()
5052
*/
5153
static void zend_ini_do_op(char type, zval *result, zval *op1, zval *op2)
@@ -86,15 +88,19 @@ static void zend_ini_do_op(char type, zval *result, zval *op1, zval *op2)
8688
}
8789

8890
str_len = zend_sprintf(str_result, "%d", i_result);
89-
ZVAL_PSTRINGL(result, str_result, str_len);
91+
ZVAL_NEW_STR(result, zend_string_init(str_result, str_len, ZEND_SYSTEM_INI));
9092
}
9193
/* }}} */
9294

9395
/* {{{ zend_ini_init_string()
9496
*/
9597
static void zend_ini_init_string(zval *result)
9698
{
97-
ZVAL_EMPTY_PSTRING(result);
99+
if (ZEND_SYSTEM_INI) {
100+
ZVAL_EMPTY_PSTRING(result);
101+
} else {
102+
ZVAL_EMPTY_STRING(result);
103+
}
98104
}
99105
/* }}} */
100106

@@ -107,7 +113,11 @@ static void zend_ini_add_string(zval *result, zval *op1, zval *op2)
107113
if (Z_TYPE_P(op1) != IS_STRING) {
108114
zend_string *str = zval_get_string(op1);
109115
/* ZEND_ASSERT(!Z_REFCOUNTED_P(op1)); */
110-
ZVAL_PSTRINGL(op1, ZSTR_VAL(str), ZSTR_LEN(str));
116+
if (ZEND_SYSTEM_INI) {
117+
ZVAL_PSTRINGL(op1, ZSTR_VAL(str), ZSTR_LEN(str));
118+
} else {
119+
ZVAL_STR(op1, str);
120+
}
111121
zend_string_release(str);
112122
}
113123
op1_len = (int)Z_STRLEN_P(op1);
@@ -117,7 +127,7 @@ static void zend_ini_add_string(zval *result, zval *op1, zval *op2)
117127
}
118128
length = op1_len + (int)Z_STRLEN_P(op2);
119129

120-
ZVAL_NEW_STR(result, zend_string_extend(Z_STR_P(op1), length, 1));
130+
ZVAL_NEW_STR(result, zend_string_extend(Z_STR_P(op1), length, ZEND_SYSTEM_INI));
121131
memcpy(Z_STRVAL_P(result) + op1_len, Z_STRVAL_P(op2), Z_STRLEN_P(op2) + 1);
122132
}
123133
/* }}} */
@@ -140,7 +150,7 @@ static void zend_ini_get_constant(zval *result, zval *name)
140150
convert_to_string(&tmp);
141151
c = &tmp;
142152
}
143-
ZVAL_PSTRINGL(result, Z_STRVAL_P(c), Z_STRLEN_P(c));
153+
ZVAL_NEW_STR(result, zend_string_init(Z_STRVAL_P(c), Z_STRLEN_P(c), ZEND_SYSTEM_INI));
144154
if (c == &tmp) {
145155
zend_string_release(Z_STR(tmp));
146156
}
@@ -160,11 +170,11 @@ static void zend_ini_get_var(zval *result, zval *name)
160170

161171
/* Fetch configuration option value */
162172
if ((curval = zend_get_configuration_directive(Z_STR_P(name))) != NULL) {
163-
ZVAL_PSTRINGL(result, Z_STRVAL_P(curval), Z_STRLEN_P(curval));
173+
ZVAL_NEW_STR(result, zend_string_init(Z_STRVAL_P(curval), Z_STRLEN_P(curval), ZEND_SYSTEM_INI));
164174
/* ..or if not found, try ENV */
165175
} else if ((envvar = zend_getenv(Z_STRVAL_P(name), Z_STRLEN_P(name))) != NULL ||
166176
(envvar = getenv(Z_STRVAL_P(name))) != NULL) {
167-
ZVAL_PSTRING(result, envvar);
177+
ZVAL_NEW_STR(result, zend_string_init(envvar, strlen(envvar), ZEND_SYSTEM_INI));
168178
} else {
169179
zend_ini_init_string(result);
170180
}
@@ -282,6 +292,8 @@ ZEND_API int zend_parse_ini_string(char *str, zend_bool unbuffered_errors, int s
282292
%left '|' '&' '^'
283293
%right '~' '!'
284294
295+
%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
296+
285297
%%
286298
287299
statement_list:

Zend/zend_ini_scanner.l

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,8 @@ ZEND_API ts_rsrc_id ini_scanner_globals_id;
110110
ZEND_API zend_ini_scanner_globals ini_scanner_globals;
111111
#endif
112112

113+
#define ZEND_SYSTEM_INI CG(ini_parser_unbuffered_errors)
114+
113115
/* Eat leading whitespace */
114116
#define EAT_LEADING_WHITESPACE() \
115117
while (yyleng) { \
@@ -137,7 +139,7 @@ ZEND_API zend_ini_scanner_globals ini_scanner_globals;
137139
#define EAT_TRAILING_WHITESPACE() EAT_TRAILING_WHITESPACE_EX('X')
138140

139141
#define zend_ini_copy_value(retval, str, len) \
140-
ZVAL_NEW_STR(retval, zend_string_init(str, len, 1))
142+
ZVAL_NEW_STR(retval, zend_string_init(str, len, ZEND_SYSTEM_INI))
141143

142144

143145
#define RETURN_TOKEN(type, str, len) { \

ext/standard/basic_functions.c

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5796,17 +5796,15 @@ PHP_FUNCTION(move_uploaded_file)
57965796
*/
57975797
static void php_simple_ini_parser_cb(zval *arg1, zval *arg2, zval *arg3, int callback_type, zval *arr)
57985798
{
5799-
zval element;
5800-
58015799
switch (callback_type) {
58025800

58035801
case ZEND_INI_PARSER_ENTRY:
58045802
if (!arg2) {
58055803
/* bare string - nothing to do */
58065804
break;
58075805
}
5808-
ZVAL_DUP(&element, arg2);
5809-
zend_symtable_update(Z_ARRVAL_P(arr), Z_STR_P(arg1), &element);
5806+
Z_TRY_ADDREF_P(arg2);
5807+
zend_symtable_update(Z_ARRVAL_P(arr), Z_STR_P(arg1), arg2);
58105808
break;
58115809

58125810
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
58365834
array_init(find_hash);
58375835
}
58385836

5839-
ZVAL_DUP(&element, arg2);
58405837
if (!arg3 || (Z_TYPE_P(arg3) == IS_STRING && Z_STRLEN_P(arg3) == 0)) {
5841-
add_next_index_zval(find_hash, &element);
5838+
Z_TRY_ADDREF_P(arg2);
5839+
add_next_index_zval(find_hash, arg2);
58425840
} else {
5843-
array_set_zval_key(Z_ARRVAL_P(find_hash), arg3, &element);
5844-
zval_ptr_dtor(&element);
5841+
array_set_zval_key(Z_ARRVAL_P(find_hash), arg3, arg2);
58455842
}
58465843
}
58475844
break;

0 commit comments

Comments
 (0)