Skip to content

Commit 51a504c

Browse files
committed
Avoid string copy in get_cfg_var()
basic_functions.c already has a macro for returning an ini value to userland, so make use of it for get_cfg_var() as well, after generalizing it to not write to return_value in particular.
1 parent 43cb254 commit 51a504c

File tree

2 files changed

+25
-37
lines changed

2 files changed

+25
-37
lines changed

Zend/Optimizer/zend_func_info.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ static const func_info_t old_func_infos[] = {
132132
F1("quoted_printable_decode", MAY_BE_STRING),
133133
F1("quoted_printable_encode", MAY_BE_STRING),
134134
F1("get_current_user", MAY_BE_STRING),
135-
F1("get_cfg_var", MAY_BE_FALSE | MAY_BE_STRING | MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_STRING | MAY_BE_ARRAY_OF_ARRAY),
135+
FN("get_cfg_var", MAY_BE_FALSE | MAY_BE_STRING | MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_STRING | MAY_BE_ARRAY_OF_ARRAY),
136136
F1("error_get_last", MAY_BE_NULL | MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_STRING | MAY_BE_ARRAY_OF_LONG | MAY_BE_ARRAY_OF_STRING),
137137
F1("serialize", MAY_BE_STRING),
138138
F1("var_export", MAY_BE_NULL | MAY_BE_STRING),

ext/standard/basic_functions.c

Lines changed: 24 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1340,25 +1340,32 @@ PHP_FUNCTION(get_current_user)
13401340
}
13411341
/* }}} */
13421342

1343+
#define ZVAL_SET_INI_STR(zv, val) do { \
1344+
if (ZSTR_IS_INTERNED(val)) { \
1345+
ZVAL_INTERNED_STR(zv, val); \
1346+
} else if (ZSTR_LEN(val) == 0) { \
1347+
ZVAL_EMPTY_STRING(zv); \
1348+
} else if (ZSTR_LEN(val) == 1) { \
1349+
ZVAL_CHAR(zv, ZSTR_VAL(val)[0]); \
1350+
} else if (!(GC_FLAGS(val) & GC_PERSISTENT)) { \
1351+
ZVAL_NEW_STR(zv, zend_string_copy(val)); \
1352+
} else { \
1353+
ZVAL_NEW_STR(zv, zend_string_init(ZSTR_VAL(val), ZSTR_LEN(val), 0)); \
1354+
} \
1355+
} while (0)
1356+
13431357
static void add_config_entries(HashTable *hash, zval *return_value);
13441358

13451359
/* {{{ add_config_entry */
13461360
static void add_config_entry(zend_ulong h, zend_string *key, zval *entry, zval *retval)
13471361
{
13481362
if (Z_TYPE_P(entry) == IS_STRING) {
1349-
zend_string *str = Z_STR_P(entry);
1350-
if (!ZSTR_IS_INTERNED(str)) {
1351-
if (!(GC_FLAGS(str) & GC_PERSISTENT)) {
1352-
zend_string_addref(str);
1353-
} else {
1354-
str = zend_string_init(ZSTR_VAL(str), ZSTR_LEN(str), 0);
1355-
}
1356-
}
1357-
1363+
zval str_zv;
1364+
ZVAL_SET_INI_STR(&str_zv, Z_STR_P(entry));
13581365
if (key) {
1359-
add_assoc_str_ex(retval, ZSTR_VAL(key), ZSTR_LEN(key), str);
1366+
add_assoc_zval_ex(retval, ZSTR_VAL(key), ZSTR_LEN(key), &str_zv);
13601367
} else {
1361-
add_index_str(retval, h, str);
1368+
add_index_zval(retval, h, &str_zv);
13621369
}
13631370
} else if (Z_TYPE_P(entry) == IS_ARRAY) {
13641371
zval tmp;
@@ -1385,23 +1392,21 @@ static void add_config_entries(HashTable *hash, zval *return_value) /* {{{ */
13851392
/* {{{ Get the value of a PHP configuration option */
13861393
PHP_FUNCTION(get_cfg_var)
13871394
{
1388-
char *varname;
1389-
size_t varname_len;
1390-
zval *retval;
1395+
zend_string *varname;
13911396

13921397
ZEND_PARSE_PARAMETERS_START(1, 1)
1393-
Z_PARAM_STRING(varname, varname_len)
1398+
Z_PARAM_STR(varname)
13941399
ZEND_PARSE_PARAMETERS_END();
13951400

1396-
retval = cfg_get_entry(varname, (uint32_t)varname_len);
1401+
zval *retval = cfg_get_entry_ex(varname);
13971402

13981403
if (retval) {
13991404
if (Z_TYPE_P(retval) == IS_ARRAY) {
14001405
array_init(return_value);
14011406
add_config_entries(Z_ARRVAL_P(retval), return_value);
14021407
return;
14031408
} else {
1404-
RETURN_STRING(Z_STRVAL_P(retval));
1409+
ZVAL_SET_INI_STR(return_value, Z_STR_P(retval));
14051410
}
14061411
} else {
14071412
RETURN_FALSE;
@@ -1947,21 +1952,6 @@ PHP_FUNCTION(highlight_string)
19471952
}
19481953
/* }}} */
19491954

1950-
#define INI_RETVAL_STR(val) do { \
1951-
/* copy to return value here, because alter might free it! */ \
1952-
if (ZSTR_IS_INTERNED(val)) { \
1953-
RETVAL_INTERNED_STR(val); \
1954-
} else if (ZSTR_LEN(val) == 0) { \
1955-
RETVAL_EMPTY_STRING(); \
1956-
} else if (ZSTR_LEN(val) == 1) { \
1957-
RETVAL_CHAR(ZSTR_VAL(val)[0]); \
1958-
} else if (!(GC_FLAGS(val) & GC_PERSISTENT)) { \
1959-
ZVAL_NEW_STR(return_value, zend_string_copy(val)); \
1960-
} else { \
1961-
ZVAL_NEW_STR(return_value, zend_string_init(ZSTR_VAL(val), ZSTR_LEN(val), 0)); \
1962-
} \
1963-
} while (0)
1964-
19651955
/* {{{ Get a configuration option */
19661956
PHP_FUNCTION(ini_get)
19671957
{
@@ -1977,7 +1967,7 @@ PHP_FUNCTION(ini_get)
19771967
RETURN_FALSE;
19781968
}
19791969

1980-
INI_RETVAL_STR(val);
1970+
ZVAL_SET_INI_STR(return_value, val);
19811971
}
19821972
/* }}} */
19831973

@@ -2082,7 +2072,7 @@ PHP_FUNCTION(ini_set)
20822072
val = zend_ini_get_value(varname);
20832073

20842074
if (val) {
2085-
INI_RETVAL_STR(val);
2075+
ZVAL_SET_INI_STR(return_value, val);
20862076
} else {
20872077
RETVAL_FALSE;
20882078
}
@@ -2116,8 +2106,6 @@ PHP_FUNCTION(ini_set)
21162106
}
21172107
/* }}} */
21182108

2119-
#undef INI_RETVAL_STR
2120-
21212109
/* {{{ Restore the value of a configuration option specified by varname */
21222110
PHP_FUNCTION(ini_restore)
21232111
{

0 commit comments

Comments
 (0)