Skip to content

Commit 97e29be

Browse files
alexdowadiluuu1994
andcommitted
Use shared, immutable array for return value of mb_list_encodings
This will allow us to easily check in other mbstring functions if the list of all supported encodings, returned by mb_list_encodings, is passed in as input to another function. Co-authored-by: Ilija Tovilo <[email protected]>
1 parent 80c8ca9 commit 97e29be

File tree

5 files changed

+26
-6
lines changed

5 files changed

+26
-6
lines changed

Zend/Optimizer/zend_func_infos.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ static const func_info_t func_infos[] = {
227227
F1("mb_strtoupper", MAY_BE_STRING),
228228
F1("mb_strtolower", MAY_BE_STRING),
229229
F1("mb_detect_encoding", MAY_BE_STRING|MAY_BE_FALSE),
230-
F1("mb_list_encodings", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_STRING),
230+
FN("mb_list_encodings", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_STRING),
231231
F1("mb_encoding_aliases", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_STRING),
232232
F1("mb_encode_mimeheader", MAY_BE_STRING),
233233
F1("mb_decode_mimeheader", MAY_BE_STRING),

ext/mbstring/mbstring.c

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1016,6 +1016,7 @@ ZEND_TSRMLS_CACHE_UPDATE();
10161016
mbstring_globals->internal_encoding_set = 0;
10171017
mbstring_globals->http_output_set = 0;
10181018
mbstring_globals->http_input_set = 0;
1019+
mbstring_globals->all_encodings_list = NULL;
10191020
}
10201021
/* }}} */
10211022

@@ -1156,6 +1157,13 @@ PHP_RSHUTDOWN_FUNCTION(mbstring)
11561157
MBSTRG(outconv_enabled) = false;
11571158
MBSTRG(outconv_state) = 0;
11581159

1160+
if (MBSTRG(all_encodings_list)) {
1161+
GC_DELREF(MBSTRG(all_encodings_list));
1162+
zend_hash_destroy(MBSTRG(all_encodings_list));
1163+
efree(MBSTRG(all_encodings_list));
1164+
MBSTRG(all_encodings_list) = NULL;
1165+
}
1166+
11591167
#ifdef HAVE_MBREGEX
11601168
PHP_RSHUTDOWN(mb_regex) (INIT_FUNC_ARGS_PASSTHRU);
11611169
#endif
@@ -3205,10 +3213,22 @@ PHP_FUNCTION(mb_list_encodings)
32053213
{
32063214
ZEND_PARSE_PARAMETERS_NONE();
32073215

3208-
array_init(return_value);
3209-
for (const mbfl_encoding **encodings = mbfl_get_supported_encodings(); *encodings; encodings++) {
3210-
add_next_index_string(return_value, (*encodings)->name);
3216+
if (MBSTRG(all_encodings_list) == NULL) {
3217+
/* Initialize shared array of supported encoding names
3218+
* This is done so that we can check if `mb_list_encodings()` is being
3219+
* passed to other mbstring functions using a cheap pointer equality check */
3220+
HashTable *array = emalloc(sizeof(HashTable));
3221+
zend_hash_init(array, 80, NULL, zval_ptr_dtor_str, false);
3222+
for (const mbfl_encoding **encodings = mbfl_get_supported_encodings(); *encodings; encodings++) {
3223+
zval tmp;
3224+
ZVAL_STRING(&tmp, (*encodings)->name);
3225+
zend_hash_next_index_insert(array, &tmp);
3226+
}
3227+
MBSTRG(all_encodings_list) = array;
32113228
}
3229+
3230+
GC_ADDREF(MBSTRG(all_encodings_list));
3231+
RETURN_ARR(MBSTRG(all_encodings_list));
32123232
}
32133233
/* }}} */
32143234

ext/mbstring/mbstring.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ ZEND_BEGIN_MODULE_GLOBALS(mbstring)
8888
size_t current_detect_order_list_size;
8989
enum mbfl_no_encoding *default_detect_order_list;
9090
size_t default_detect_order_list_size;
91+
HashTable *all_encodings_list;
9192
int filter_illegal_mode;
9293
uint32_t filter_illegal_substchar;
9394
int current_filter_illegal_mode;

ext/mbstring/mbstring.stub.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,6 @@ function mb_detect_encoding(string $string, array|string|null $encodings = null,
140140

141141
/**
142142
* @return array<int, string>
143-
* @refcount 1
144143
*/
145144
function mb_list_encodings(): array {}
146145

ext/mbstring/mbstring_arginfo.h

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)