23#include "libmbfl/config.h"
85static void php_mb_populate_current_detect_order_list(
void);
87static int php_mb_encoding_translation(
void);
89static void php_mb_gpc_get_detect_order(
const zend_encoding ***list,
size_t *list_size);
93static inline bool php_mb_is_unsupported_no_encoding(
enum mbfl_no_encoding no_enc);
99static const mbfl_encoding* mb_guess_encoding(
unsigned char *in,
size_t in_len,
const mbfl_encoding **elist,
unsigned int elist_size,
bool strict,
bool order_significant);
177 {
mbfl_no_language_japanese, php_mb_default_identify_list_ja,
sizeof(php_mb_default_identify_list_ja) /
sizeof(php_mb_default_identify_list_ja[0]) },
178 {
mbfl_no_language_korean, php_mb_default_identify_list_kr,
sizeof(php_mb_default_identify_list_kr) /
sizeof(php_mb_default_identify_list_kr[0]) },
181 {
mbfl_no_language_russian, php_mb_default_identify_list_ru,
sizeof(php_mb_default_identify_list_ru) /
sizeof(php_mb_default_identify_list_ru[0]) },
182 {
mbfl_no_language_armenian, php_mb_default_identify_list_hy,
sizeof(php_mb_default_identify_list_hy) /
sizeof(php_mb_default_identify_list_hy[0]) },
183 {
mbfl_no_language_turkish, php_mb_default_identify_list_tr,
sizeof(php_mb_default_identify_list_tr) /
sizeof(php_mb_default_identify_list_tr[0]) },
184 {
mbfl_no_language_ukrainian, php_mb_default_identify_list_ua,
sizeof(php_mb_default_identify_list_ua) /
sizeof(php_mb_default_identify_list_ua[0]) },
185 {
mbfl_no_language_neutral, php_mb_default_identify_list_neut,
sizeof(php_mb_default_identify_list_neut) /
sizeof(php_mb_default_identify_list_neut[0]) }
226#ifdef COMPILE_DL_MBSTRING
245 if (last_encoding_name && (last_encoding_name == encoding_name
260 php_error_docref(
NULL,
E_DEPRECATED,
"Handling HTML entities via mbstring is deprecated; use htmlspecialchars, htmlentities, or mb_encode_numericentity/mb_decode_numericentity instead");
266 if (last_encoding_name) {
267 zend_string_release(last_encoding_name);
277static const mbfl_encoding *php_mb_get_encoding_or_pass(
const char *encoding_name,
size_t encoding_name_len) {
278 if (
strncmp(encoding_name,
"pass", encoding_name_len) == 0) {
285static size_t count_commas(
const char *
p,
const char *
end) {
287 while ((
p = memchr(
p,
',',
end -
p))) {
298static zend_result php_mb_parse_encoding_list(
const char *
value,
size_t value_length,
301 if (
value ==
NULL || value_length == 0) {
308 const char *p1, *endp, *tmpstr;
311 if (
value[0]==
'"' &&
value[value_length-1]==
'"' && value_length>2) {
318 endp = tmpstr + value_length;
326 const char *comma = memchr(p1,
',', endp - p1);
327 const char *
p = comma ? comma : endp;
329 while (p1 <
p && (*p1 ==
' ' || *p1 ==
'\t')) {
333 while (
p > p1 && (*
p ==
' ' || *
p ==
'\t')) {
336 size_t p1_length =
p - p1 + 1;
339 if (!included_auto) {
344 for (i = 0; i < identify_list_size; i++) {
383 size_t *return_size, uint32_t
arg_num)
389 bool included_auto = 0;
393 zend_string *encoding_str = zval_try_get_string(hash_entry);
400 if (!included_auto) {
406 for (
j = 0;
j < identify_list_size;
j++) {
418 zend_string_release(encoding_str);
423 zend_string_release(encoding_str);
432static const zend_encoding* php_mb_zend_encoding_fetcher(
const char *encoding_name)
442static bool php_mb_zend_encoding_lexer_compatibility_checker(
const zend_encoding *_encoding)
448static const zend_encoding *php_mb_zend_encoding_detector(
const unsigned char *arg_string,
size_t arg_length,
const zend_encoding **list,
size_t list_size)
459 return (
const zend_encoding*)mb_guess_encoding((
unsigned char*)arg_string, arg_length, (
const mbfl_encoding**)list, list_size,
false,
false);
462static size_t php_mb_zend_encoding_converter(
unsigned char **to,
size_t *to_length,
const unsigned char *from,
size_t from_length,
const zend_encoding *encoding_to,
const zend_encoding *encoding_from)
464 unsigned int num_errors = 0;
475static zend_result php_mb_zend_encoding_list_parser(
const char *encoding_list,
size_t encoding_list_len,
const zend_encoding ***return_list,
size_t *return_size,
bool persistent)
477 return php_mb_parse_encoding_list(
478 encoding_list, encoding_list_len,
483static const zend_encoding *php_mb_zend_internal_encoding_getter(
void)
496 php_mb_zend_encoding_fetcher,
497 php_mb_zend_encoding_name_getter,
498 php_mb_zend_encoding_lexer_compatibility_checker,
499 php_mb_zend_encoding_detector,
500 php_mb_zend_encoding_converter,
501 php_mb_zend_encoding_list_parser,
502 php_mb_zend_internal_encoding_getter,
503 php_mb_zend_internal_encoding_setter
508static void *_php_mb_compile_regex(
const char *pattern)
525static int _php_mb_match_regex(
void *opaque,
const char *str,
size_t str_len)
530 if (
NULL == match_data) {
543static void _php_mb_free_regex(
void *opaque)
555 *plist_size =
sizeof(php_mb_default_identify_list_neut) /
sizeof(php_mb_default_identify_list_neut[0]);
557 for (i = 0; i <
sizeof(php_mb_default_identify_list) /
sizeof(php_mb_default_identify_list[0]); i++) {
558 if (php_mb_default_identify_list[i].lang == lang) {
560 *plist_size = php_mb_default_identify_list[i].list_size;
574 for (i = 0; i <
len &&
start[i] != quote; ++i) {
575 if (
start[i] ==
'\\' && (
start[i + 1] ==
'\\' || (quote &&
start[i + 1] == quote))) {
576 *resp++ =
start[++i];
580 while (
j-- > 0 && i <
len) {
581 *resp++ =
start[i++];
596 while (*
pos && *
pos != stop) {
597 if ((quote = *
pos) ==
'"' || quote ==
'\'') {
599 while (*
pos && *
pos != quote) {
600 if (*
pos ==
'\\' &&
pos[1] &&
pos[1] == quote) {
622 while (*
pos == stop) {
633 while (*str && isspace(*(
unsigned char *)str)) {
641 if (*str ==
'"' || *str ==
'\'') {
645 return php_mb_rfc1867_substring_conf(
encoding, str,
strlen(str), quote);
649 while (*strend && !isspace(*(
unsigned char *)strend)) {
652 return php_mb_rfc1867_substring_conf(
encoding, str, strend - str, 0);
704static PHP_INI_MH(OnUpdate_mbstring_detect_order)
731static zend_result _php_mb_ini_mbstring_http_input_set(
const char *new_value,
size_t new_value_length) {
734 if (new_value_length == 4 &&
strncmp(new_value,
"pass", 4) == 0) {
738 }
else if (
FAILURE == php_mb_parse_encoding_list(new_value, new_value_length, &list, &
size, 1, 0) ||
size == 0) {
750static PHP_INI_MH(OnUpdate_mbstring_http_input)
756 if (!new_value || !
ZSTR_LEN(new_value)) {
764 return _php_mb_ini_mbstring_http_input_set(
ZSTR_VAL(new_value),
ZSTR_LEN(new_value));
768static zend_result _php_mb_ini_mbstring_http_output_set(
const char *new_value,
size_t length) {
780static PHP_INI_MH(OnUpdate_mbstring_http_output)
794 return _php_mb_ini_mbstring_http_output_set(
ZSTR_VAL(new_value),
ZSTR_LEN(new_value));
799static zend_result _php_mb_ini_mbstring_internal_encoding_set(
const char *new_value,
size_t new_value_length)
814 const char *enc_name = new_value;
815 if (
FAILURE == php_mb_regex_set_default_mbctype(enc_name)) {
818 php_mb_regex_set_default_mbctype(enc_name);
820 php_mb_regex_set_mbctype(new_value);
828static PHP_INI_MH(OnUpdate_mbstring_internal_encoding)
834 if (OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage) ==
FAILURE) {
838 if (new_value &&
ZSTR_LEN(new_value)) {
840 return _php_mb_ini_mbstring_internal_encoding_set(
ZSTR_VAL(new_value),
ZSTR_LEN(new_value));
850static PHP_INI_MH(OnUpdate_mbstring_substitute_character)
852 if (new_value !=
NULL) {
887static PHP_INI_MH(OnUpdate_mbstring_encoding_translation)
889 if (new_value ==
NULL) {
893 OnUpdateBool(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage);
908static PHP_INI_MH(OnUpdate_mbstring_http_output_conv_mimetypes)
914 new_value = entry->orig_value;
919 if (!(re = _php_mb_compile_regex(
ZSTR_VAL(tmp)))) {
948 OnUpdate_mbstring_encoding_translation,
951 "^(text/|application/xhtml\\+xml)",
953 OnUpdate_mbstring_http_output_conv_mimetypes)
960 STD_PHP_INI_ENTRY(
"mbstring.regex_stack_limit",
"100000",
PHP_INI_ALL, OnUpdateLong, regex_stack_limit, zend_mbstring_globals, mbstring_globals)
961 STD_PHP_INI_ENTRY(
"mbstring.regex_retry_limit",
"1000000",
PHP_INI_ALL, OnUpdateLong, regex_retry_limit, zend_mbstring_globals, mbstring_globals)
966static
void mbstring_internal_encoding_changed_hook(
void) {
987#if defined(COMPILE_DL_MBSTRING) && defined(ZTS)
992 mbstring_globals->internal_encoding =
NULL;
993 mbstring_globals->current_internal_encoding = mbstring_globals->internal_encoding;
996 mbstring_globals->http_input_identify =
NULL;
997 mbstring_globals->http_input_identify_get =
NULL;
998 mbstring_globals->http_input_identify_post =
NULL;
999 mbstring_globals->http_input_identify_cookie =
NULL;
1000 mbstring_globals->http_input_identify_string =
NULL;
1001 mbstring_globals->http_input_list =
NULL;
1002 mbstring_globals->http_input_list_size = 0;
1003 mbstring_globals->detect_order_list =
NULL;
1004 mbstring_globals->detect_order_list_size = 0;
1005 mbstring_globals->current_detect_order_list =
NULL;
1006 mbstring_globals->current_detect_order_list_size = 0;
1007 mbstring_globals->default_detect_order_list = (
enum mbfl_no_encoding *) php_mb_default_identify_list_neut;
1008 mbstring_globals->default_detect_order_list_size =
sizeof(php_mb_default_identify_list_neut) /
sizeof(php_mb_default_identify_list_neut[0]);
1010 mbstring_globals->filter_illegal_substchar =
'?';
1012 mbstring_globals->current_filter_illegal_substchar =
'?';
1013 mbstring_globals->illegalchars = 0;
1014 mbstring_globals->encoding_translation = 0;
1015 mbstring_globals->strict_detection = 0;
1016 mbstring_globals->outconv_enabled =
false;
1017 mbstring_globals->outconv_state = 0;
1018 mbstring_globals->http_output_conv_mimetypes =
NULL;
1020 mbstring_globals->mb_regex_globals = php_mb_regex_globals_alloc();
1022 mbstring_globals->last_used_encoding_name =
NULL;
1023 mbstring_globals->last_used_encoding =
NULL;
1024 mbstring_globals->internal_encoding_set = 0;
1025 mbstring_globals->http_output_set = 0;
1026 mbstring_globals->http_input_set = 0;
1027 mbstring_globals->all_encodings_list =
NULL;
1034 if (mbstring_globals->http_input_list) {
1035 free(
ZEND_VOIDP(mbstring_globals->http_input_list));
1037 if (mbstring_globals->detect_order_list) {
1038 free(
ZEND_VOIDP(mbstring_globals->detect_order_list));
1040 if (mbstring_globals->http_output_conv_mimetypes) {
1041 _php_mb_free_regex(mbstring_globals->http_output_conv_mimetypes);
1044 php_mb_regex_globals_free(mbstring_globals->mb_regex_globals);
1049#ifdef ZEND_INTRIN_AVX2_FUNC_PTR
1050static void init_check_utf8(
void);
1056#if defined(COMPILE_DL_MBSTRING) && defined(ZTS)
1065 mbstring_internal_encoding_changed_hook();
1079 register_mbstring_symbols(module_number);
1086 php_mb_encoding_translation,
1087 php_mb_gpc_get_detect_order,
1088 php_mb_gpc_set_input_encoding,
1089 php_mb_rfc1867_getword,
1090 php_mb_rfc1867_getword_conf,
1091 php_mb_rfc1867_basename);
1093#ifdef ZEND_INTRIN_AVX2_FUNC_PTR
1095 init_convert_utf16();
1129 php_mb_populate_current_detect_order_list();
1197 php_info_print_table_header(1,
"mbstring extension makes use of \"streamable kanji code filter and converter\", which is distributed under the GNU Lesser General Public License version 2.1.");
1268 size_t type_len = 0,
n;
1279 }
else if (type_len != 1) {
1281 "must be one of \"G\", \"P\", \"C\", \"S\", \"I\", or \"L\"");
1306 for (
size_t i = 0; i <
n; i++, entry++) {
1319 for (
size_t i = 0; i <
n; i++, entry++) {
1321 smart_str_appendc(&
result,
',');
1323 smart_str_appends(&
result, (*entry)->name);
1328 "must be one of \"G\", \"P\", \"C\", \"S\", \"I\", or \"L\"");
1381 if (!order_str && !order_ht) {
1385 for (
size_t i = 0; i <
n; i++) {
1393 if (
FAILURE == php_mb_parse_encoding_array(order_ht, &list, &
size, 1)) {
1418static inline bool php_mb_check_code_point(
zend_long cp)
1420 if (cp < 0 || cp >= 0x110000) {
1425 if (
cp >= 0xd800 &&
cp <= 0xdfff) {
1442 bool substitute_is_null = 1;
1449 if (substitute_is_null) {
1462 if (substitute_character !=
NULL) {
1480 if (!php_mb_check_code_point(substitute_codepoint)) {
1508 if (preferred_name ==
NULL || *preferred_name ==
'\0') {
1531 track_vars_array = zend_try_array_init(track_vars_array);
1532 if (!track_vars_array) {
1536 encstr =
estrndup(encstr, encstr_len);
1571 bool free_mimetype =
false;
1572 char *mimetype =
NULL;
1575 if (
SG(sapi_headers).mimetype
1580 mimetype =
estrdup(
SG(sapi_headers).mimetype);
1582 mimetype =
estrndup(
SG(sapi_headers).mimetype,
s -
SG(sapi_headers).mimetype);
1584 free_mimetype =
true;
1585 }
else if (
SG(sapi_headers).send_default_content_type) {
1590 if (
SG(sapi_headers).send_default_content_type || free_mimetype) {
1596 SG(sapi_headers).send_default_content_type = 0;
1603 if (free_mimetype) {
1615 uint32_t wchar_buf[128];
1616 unsigned char *in = (
unsigned char*)
ZSTR_VAL(str);
1623 encoding->from_wchar(wchar_buf, out_len, &
buf, !in_len && last_feed);
1647 if (split_len <= 0) {
1650 }
else if (split_len > UINT_MAX / 4) {
1668 unsigned int chunk_len = char_len * split_len;
1669 unsigned int chunks = ((
ZSTR_LEN(str) / chunk_len) + split_len - 1) / split_len;
1682 unsigned char *chunk =
p;
1684 for (
int char_count = 0; char_count < split_len &&
p < e; char_count++) {
1696 uint32_t wchar_buf[128];
1698 unsigned int state = 0, char_count = 0;
1703 size_t out_len = enc->
to_wchar(&
p, &in_len, wchar_buf, 128, &
state);
1709 if (out_len >= split_len - char_count) {
1712 enc->
from_wchar(wchar_buf, split_len - char_count, &
buf,
true);
1713 i += split_len - char_count;
1720 char_count += out_len;
1725 while (i < out_len) {
1729 if (out_len - i >= split_len) {
1737 char_count = out_len - i;
1756static inline uint32_t _mm_sum_epu8(
const __m128i
v)
1764 __m128i vsum = _mm_sad_epu8(
v, _mm_setzero_si128());
1769 return _mm_cvtsi128_si32(vsum) + _mm_extract_epi16(vsum, 4);
1778static size_t mb_fast_strlen_utf8(
unsigned char *
p,
size_t len)
1780 unsigned char *e =
p +
len;
1783 if (
len >=
sizeof(__m128i)) {
1784 e -=
sizeof(__m128i);
1786 const __m128i threshold = _mm_set1_epi8(-64);
1787 const __m128i delta = _mm_set1_epi8(1);
1788 __m128i counter = _mm_setzero_si128();
1790 unsigned char reset_counter = 255;
1792 __m128i operand = _mm_loadu_si128((__m128i*)
p);
1793 __m128i lt = _mm_cmplt_epi8(operand, threshold);
1794 counter = _mm_add_epi8(counter, _mm_and_si128(lt, delta));
1798 if (--reset_counter == 0) {
1799 len -= _mm_sum_epu8(counter);
1800 counter = _mm_setzero_si128();
1801 reset_counter = 255;
1804 p +=
sizeof(__m128i);
1807 e +=
sizeof(__m128i);
1808 len -= _mm_sum_epu8(counter);
1814 signed char c = *
p++;
1827 return ZSTR_LEN(
string) / char_len;
1829 return mb_fast_strlen_utf8((
unsigned char*)
ZSTR_VAL(
string),
ZSTR_LEN(
string));
1832 uint32_t wchar_buf[128];
1833 unsigned char *in = (
unsigned char*)
ZSTR_VAL(
string);
1835 unsigned int state = 0;
1856 const mbfl_encoding *enc = php_mb_get_encoding(enc_name, 2);
1871static unsigned char* offset_to_pointer_utf8(
unsigned char *str,
unsigned char *
end, ssize_t
offset) {
1873 unsigned char *
pos =
end;
1879 unsigned char c = *--
pos;
1880 if (c < 0x80 || (c & 0xC0) != 0x80) {
1887 unsigned char *
pos = str;
1898static size_t pointer_to_offset_utf8(
unsigned char *
start,
unsigned char *
pos) {
1906 unsigned char *offset_pointer;
1908 if (!php_mb_is_no_encoding_utf8(enc->
no_encoding)) {
1909 unsigned int num_errors = 0;
1913 haystack_u8 = haystack;
1917 offset_pointer = offset_to_pointer_utf8((
unsigned char*)
ZSTR_VAL(haystack_u8), (
unsigned char*)
ZSTR_VAL(haystack_u8) +
ZSTR_LEN(haystack_u8),
offset);
1918 if (!offset_pointer) {
1928 const char *found_pos;
1931 }
else if (
offset >= 0) {
1934 size_t needle_len = pointer_to_offset_utf8((
unsigned char*)
ZSTR_VAL(needle), (
unsigned char*)
ZSTR_VAL(needle) +
ZSTR_LEN(needle));
1935 offset_pointer = offset_to_pointer_utf8(offset_pointer, (
unsigned char*)
ZSTR_VAL(haystack_u8) +
ZSTR_LEN(haystack_u8), needle_len);
1936 if (!offset_pointer) {
1937 offset_pointer = (
unsigned char*)
ZSTR_VAL(haystack_u8) +
ZSTR_LEN(haystack_u8);
1940 found_pos = zend_memnrstr(
ZSTR_VAL(haystack_u8),
ZSTR_VAL(needle_u8),
ZSTR_LEN(needle_u8), (
const char*)offset_pointer);
1944 result = pointer_to_offset_utf8((
unsigned char*)
ZSTR_VAL(haystack_u8), (
unsigned char*)found_pos);
1948 if (haystack_u8 != haystack) {
1949 zend_string_free(haystack_u8);
1951 if (needle_u8 != needle) {
1952 zend_string_free(needle_u8);
1957static void handle_strpos_error(
size_t error) {
1987 const mbfl_encoding *enc = php_mb_get_encoding(enc_name, 4);
1992 size_t n = mb_find_strpos(haystack, needle, enc,
offset,
false);
1993 if (!mbfl_is_error(
n)) {
1996 handle_strpos_error(
n);
2016 const mbfl_encoding *enc = php_mb_get_encoding(enc_name, 4);
2021 size_t n = mb_find_strpos(haystack, needle, enc,
offset,
true);
2022 if (!mbfl_is_error(
n)) {
2025 handle_strpos_error(
n);
2046 const mbfl_encoding *enc = php_mb_get_encoding(from_encoding, 4);
2053 if (!mbfl_is_error(
n)) {
2056 handle_strpos_error(
n);
2077 const mbfl_encoding *enc = php_mb_get_encoding(from_encoding, 4);
2084 if (!mbfl_is_error(
n)) {
2087 handle_strpos_error(
n);
2095 uint32_t wchar_buf[128];
2096 unsigned int state = 0;
2101 while (in_len &&
len) {
2102 size_t out_len = enc->
to_wchar(&in, &in_len, wchar_buf, 128, &
state);
2105 if (from >= out_len) {
2108 size_t needed_codepoints =
MIN(out_len - from,
len);
2109 enc->
from_wchar(wchar_buf + from, needed_codepoints, &
buf, !in_len || out_len >=
len);
2111 len -= needed_codepoints;
2115 return mb_convert_buf_result(&
buf, enc);
2120 unsigned char *in = (
unsigned char*)
ZSTR_VAL(input);
2137 if (from >= in_len) {
2145 return zend_string_init_fast((
const char*)in,
len);
2148 return mb_get_substr_slow(in, in_len, from,
len, enc);
2154#define MB_STRRICHR 4
2158 bool reverse_mode =
false, part =
false;
2171 const mbfl_encoding *enc = php_mb_get_encoding(encoding_name, 4);
2177 reverse_mode =
true;
2183 n = mb_find_strpos(haystack, needle, enc, 0, reverse_mode);
2186 if (!mbfl_is_error(
n)) {
2247 const mbfl_encoding *enc = php_mb_get_encoding(enc_name, 3);
2252 if (php_mb_is_no_encoding_utf8(enc->
no_encoding)) {
2256 haystack_u8 = haystack;
2258 unsigned int num_errors = 0;
2268 unsigned int num_errors = 0;
2275 unsigned int num_errors = 0;
2281 zend_string_free(haystack_u8);
2282 zend_string_free(needle_u8);
2305 if (haystack_u8 != haystack) {
2306 zend_string_free(haystack_u8);
2308 if (needle_u8 != needle) {
2309 zend_string_free(needle_u8);
2320 size_t real_from, real_len;
2321 bool len_is_null =
true;
2347 if (from < 0 || (!len_is_null &&
len < 0)) {
2348 mblen = mb_get_strlen(str, enc);
2354 real_from = (size_t) from;
2355 }
else if (-from < mblen) {
2356 real_from = mblen + from;
2365 }
else if (
len >= 0) {
2366 real_len = (size_t)
len;
2367 }
else if (real_from < mblen && -
len < mblen - real_from) {
2368 real_len = (mblen - real_from) +
len;
2373 RETVAL_STR(mb_get_substr(str, real_from, real_len, enc));
2383 bool len_is_null =
true;
2399 string.val = (
unsigned char*)string_val;
2400 string.encoding = enc;
2409 from =
string.len + from;
2418 len = (
string.len - from) +
len;
2424 if (from >
string.
len ||
len == 0) {
2436 if (
len >
string.
len - from) {
2437 len =
string.len - from;
2439 RETURN_STR(zend_string_init_fast((
const char*)(
string.
val + from),
len & -char_len));
2444 const unsigned char *
p, *q, *
end;
2447 for (
p = (
const unsigned char*)
string.
val, q =
p + from;
p < q;
p += (m = mbtab[*
p]));
2451 const unsigned char *
start =
p;
2453 if (
len >=
string.
len - (
start - (
const unsigned char*)
string.
val)) {
2454 end = (
const unsigned char*)(
string.
val +
string.
len);
2456 for (q =
p +
len;
p < q;
p += (m = mbtab[*
p]));
2474static size_t character_width(uint32_t c)
2481 unsigned int lo = 0, hi =
sizeof(mbfl_eaw_table) /
sizeof(mbfl_eaw_table[0]);
2483 unsigned int probe = (lo + hi) / 2;
2484 if (c < mbfl_eaw_table[probe].
begin) {
2486 }
else if (c > mbfl_eaw_table[probe].
end) {
2499 uint32_t wchar_buf[128];
2500 unsigned char *in = (
unsigned char*)
ZSTR_VAL(
string);
2502 unsigned int state = 0;
2505 size_t out_len = enc->
to_wchar(&in, &in_len, wchar_buf, 128, &
state);
2512 width += character_width(wchar_buf[--out_len]);
2530 const mbfl_encoding *enc = php_mb_get_encoding(enc_name, 2);
2540 uint32_t wchar_buf[128];
2541 unsigned char *in = (
unsigned char*)
ZSTR_VAL(input);
2543 unsigned int state = 0;
2544 size_t remaining_width = width;
2545 size_t to_skip = from;
2547 bool first_call =
true, input_err =
false;
2551 out_len = enc->
to_wchar(&in, &in_len, wchar_buf, 128, &
state);
2554 if (out_len <= to_skip) {
2557 for (
size_t i = to_skip; i < out_len; i++) {
2558 uint32_t w = wchar_buf[i];
2559 size_t current_w_width = character_width(w);
2563 if (remaining_width < current_w_width) {
2564 size_t marker_width = mb_get_strwidth(marker, enc);
2567 if (width <= marker_width) {
2568 return zend_string_copy(marker);
2572 width -= marker_width;
2579 goto dont_restart_conversion;
2581 goto restart_conversion;
2584 remaining_width -= current_w_width;
2597 return zend_string_copy(input);
2612 in = (
unsigned char*)
ZSTR_VAL(input);
2617 out_len = enc->
to_wchar(&in, &in_len, wchar_buf, 128, &
state);
2620dont_restart_conversion:
2621 if (out_len <= from) {
2624 for (
size_t i = from; i < out_len; i++) {
2625 size_t current_wchar_char_width = character_width(wchar_buf[i]);
2626 if (width < current_wchar_char_width) {
2628 goto append_trim_marker;
2630 width -= current_wchar_char_width;
2633 enc->
from_wchar(wchar_buf + from, out_len - from, &
buf,
false);
2646 return mb_convert_buf_result_raw(&
buf);
2670 size_t str_len = mb_get_strlen(str, enc);
2674 if (from < 0 || from > str_len) {
2682 "passing a negative integer to argument #3 ($width) is deprecated");
2683 width += mb_get_strwidth(str, enc);
2686 zend_string *trimmed = mb_get_substr(str, 0, from, enc);
2687 width -= mb_get_strwidth(trimmed, enc);
2688 zend_string_free(trimmed);
2697 RETVAL_STR(mb_trim_string(str, trimmarker, enc, from, width));
2702static inline bool php_mb_is_unsupported_no_encoding(
enum mbfl_no_encoding no_enc)
2712 unsigned int num_errors = 0;
2724 if (num_from_encodings == 1) {
2725 from_encoding = *from_encodings;
2728 from_encoding = mb_guess_encoding((
unsigned char*)input, length, from_encodings, num_from_encodings,
MBSTRG(
strict_detection),
true);
2729 if (!from_encoding) {
2743 zval *entry, entry_tmp;
2760 if (!converted_key) {
2763 key = converted_key;
2771 if (!converted_key) {
2773 zend_string_release(
key);
2777 ZVAL_STR(&entry_tmp, converted_key);
2789 Z_ARRVAL_P(entry), to_encoding, from_encodings, num_from_encodings);
2802 zend_string_release(
key);
2809 zend_string_release(
key);
2820static void remove_non_encodings_from_elist(
const mbfl_encoding **elist,
size_t *
size)
2825 unsigned int shift = 0;
2826 for (
unsigned int i = 0; i < *
size; i++) {
2844 size_t num_from_encodings;
2845 bool free_from_encodings =
false;
2854 const mbfl_encoding *to_encoding = php_mb_get_encoding(to_encoding_name, 2);
2859 if (from_encodings_ht) {
2860 if (php_mb_parse_encoding_array(from_encodings_ht, &from_encodings, &num_from_encodings, 3) ==
FAILURE) {
2863 free_from_encodings =
true;
2864 }
else if (from_encodings_str) {
2865 if (php_mb_parse_encoding_list(
ZSTR_VAL(from_encodings_str),
ZSTR_LEN(from_encodings_str),
2866 &from_encodings, &num_from_encodings,
2870 free_from_encodings =
true;
2873 num_from_encodings = 1;
2876 if (num_from_encodings > 1) {
2877 remove_non_encodings_from_elist(from_encodings, &num_from_encodings);
2880 if (!num_from_encodings) {
2896 input_ht, to_encoding, from_encodings, num_from_encodings);
2900 if (free_from_encodings) {
2923 const mbfl_encoding *enc = php_mb_get_encoding(from_encoding, 3);
2946 const mbfl_encoding *enc = php_mb_get_encoding(from_encoding, 2);
2964 const mbfl_encoding *enc = php_mb_get_encoding(from_encoding, 2);
2982 const
mbfl_encoding *enc = php_mb_get_encoding(from_encoding, 2);
2987 zend_string *first = mb_get_substr(str, 0, 1, enc);
2990 if (zend_string_equals(first,
head)) {
3022static bool is_trim_wchar(uint32_t w,
const HashTable *
ht,
const uint32_t *default_chars,
size_t default_chars_length)
3025 return zend_hash_index_exists(
ht, w);
3027 for (
size_t i = 0; i < default_chars_length; i++) {
3028 if (w == default_chars[i]) {
3038 unsigned char *in = (
unsigned char*)
ZSTR_VAL(str);
3039 uint32_t wchar_buf[128];
3042 unsigned int state = 0;
3045 size_t total_len = 0;
3048 out_len = enc->
to_wchar(&in, &in_len, wchar_buf, 128, &
state);
3050 total_len += out_len;
3052 for (
size_t i = 0; i < out_len; i++) {
3053 uint32_t w = wchar_buf[i];
3054 if (is_trim_wchar(w, what_ht, default_chars, default_chars_length)) {
3071 return zend_string_copy(str);
3073 return mb_get_substr(str,
left, total_len - (
right +
left), enc);
3078 const uint32_t trim_default_chars[] = {
3079 0x20, 0x0C, 0x0A, 0x0D, 0x09, 0x0B, 0x00, 0xA0, 0x1680,
3080 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007,
3081 0x2008, 0x2009, 0x200A, 0x2028, 0x2029, 0x202F, 0x205F, 0x3000,
3084 size_t trim_default_chars_length =
sizeof(trim_default_chars) /
sizeof(uint32_t);
3092 for (
size_t i = 0; i < trim_default_chars_length; i++) {
3103 unsigned char *what_in = (
unsigned char*)
ZSTR_VAL(what);
3104 uint32_t what_wchar_buf[128];
3105 size_t what_out_len = 0;
3106 unsigned int state = 0;
3110 bool hash_initialized =
false;
3113 what_out_len = enc->
to_wchar(&what_in, &what_len, what_wchar_buf, 128, &
state);
3116 if (what_out_len <= 4 && !hash_initialized) {
3117 return trim_each_wchar(str,
NULL, what_wchar_buf, what_out_len,
mode, enc);
3119 if (!hash_initialized) {
3120 hash_initialized =
true;
3124 for (
size_t i = 0; i < what_out_len; i++) {
3132 return zend_string_copy(str);
3188static unsigned int estimate_demerits(uint32_t w)
3222 }
else if (w >= 0x21 && w <= 0x2F) {
3224 }
else if ((rare_codepoint_bitvec[w >> 5] >> (w & 0x1F)) & 1) {
3241static size_t init_candidate_array(
struct candidate *array,
size_t length,
const mbfl_encoding **encodings,
const unsigned char **in,
size_t *in_len,
size_t n,
bool strict,
bool order_significant)
3245 for (
size_t i = 0; i < length; i++) {
3255 for (
size_t k = 0; k <
n; k++) {
3256 if (!enc->
check((
unsigned char*)in[k], in_len[k])) {
3269 array[
j].
multiplier = order_significant ? 1.0 + ((0.3 * i) / length) : 1.0;
3277static void start_string(
struct candidate *array,
size_t length,
const unsigned char *in,
size_t in_len)
3279 for (
size_t i = 0; i < length; i++) {
3283 array[i].
in_len = in_len;
3287 if (in_len >= 3 && in[0] == 0xEF && in[1] == 0xBB && in[2] == 0xBF) {
3292 if (in_len >= 2 && in[0] == 0xFE && in[1] == 0xFF) {
3297 if (in_len >= 2 && in[0] == 0xFF && in[1] == 0xFE) {
3305static size_t count_demerits(
struct candidate *array,
size_t length,
bool strict)
3307 uint32_t wchar_buf[128];
3308 unsigned int finished = 0;
3310 for (
size_t i = 0; i < length; i++) {
3311 if (array[i].in_len == 0) {
3316 while ((strict || length > 1) && finished < length) {
3318 for (
size_t i = length - 1; i != (size_t)-1; i--) {
3320 if (array[i].in_len) {
3322 size_t out_len = enc->
to_wchar((
unsigned char**)&array[i].in, &array[i].in_len, wchar_buf, 128, &array[i].
state);
3327 uint32_t w = wchar_buf[--out_len];
3336 goto try_next_encoding;
3341 array[i].
demerits += estimate_demerits(w);
3344 if (array[i].in_len == 0) {
3352 for (
size_t i = 0; i < length; i++) {
3353 double demerits = array[i].
demerits * (double) array[i].multiplier;
3354 array[i].
demerits = demerits < (double) UINT64_MAX ? (uint64_t) demerits : UINT64_MAX;
3362 if (elist_size == 0) {
3365 if (elist_size == 1) {
3375 if (
n == 1 && *str_lengths == 0) {
3381 elist_size = init_candidate_array(array, elist_size, elist, strings, str_lengths,
n, strict, order_significant);
3384 start_string(array, elist_size, strings[
n], str_lengths[
n]);
3385 elist_size = count_demerits(array, elist_size, strict);
3386 if (elist_size == 0) {
3393 unsigned int best = 0;
3394 for (
unsigned int i = 1; i < elist_size; i++) {
3399 return array[best].
enc;
3405static const mbfl_encoding* mb_guess_encoding(
unsigned char *
in,
size_t in_len,
const mbfl_encoding **elist,
unsigned int elist_size,
bool strict,
bool order_significant)
3415 bool strict =
false;
3430 bool order_significant =
true;
3435 order_significant =
false;
3437 if (
FAILURE == php_mb_parse_encoding_array(encoding_ht, &elist, &
size, 2)) {
3440 }
else if (encoding_str) {
3455 remove_non_encodings_from_elist(elist, &
size);
3468 ret = mb_guess_encoding((
unsigned char*)
ZSTR_VAL(str),
ZSTR_LEN(str), elist,
size, strict, order_significant);
3515 encoding = php_mb_get_encoding(encoding_name, 1);
3522 for (
const char **alias =
encoding->aliases; *alias; ++alias) {
3535 uint32_t wchar_buf[64], converted_buf[64 * 2];
3536 unsigned int buf_offset = 0;
3537 unsigned int state = 0;
3538 unsigned char *
in = (
unsigned char*)
ZSTR_VAL(input);
3545 uint32_t *converted = converted_buf;
3549 out_len += buf_offset;
3556 for (
size_t i = 0; i < out_len-1; i++) {
3557 uint32_t second = 0;
3558 bool consumed =
false;
3561 *converted++ = second;
3565 if (i == out_len-1) {
3569 goto emit_converted_kana;
3576 uint32_t second = 0;
3579 *converted++ = second;
3583 wchar_buf[0] = wchar_buf[out_len-1];
3595 'A',
'R',
'N',
'S',
'K',
'H',
'M',
'C',
3596 'a',
'r',
'n',
's',
'k',
'h',
'm',
'c',
3604 char *optstr =
NULL;
3615 if (optstr !=
NULL) {
3616 char *
p = optstr, *e =
p + optstr_len;
3625 }
else if (c ==
'a') {
3641 if (((opt & 0xFF00) >> 8) & opt) {
3645 int badflag = ((opt & 0xFF00) >> 8) & opt, i;
3646 for (i = 0; (badflag & 1) == 0; badflag >>= 1, i++);
3694static unsigned int mb_recursive_count_strings(
zval *var)
3696 unsigned int count = 0;
3713 count += mb_recursive_count_strings(entry);
3725static bool mb_recursive_find_strings(
zval *var,
const unsigned char **val_list,
size_t *len_list,
unsigned int *
count)
3745 if (mb_recursive_find_strings(entry, val_list, len_list,
count)) {
3764 zval *entry, *orig_var;
3802 if (mb_recursive_convert_variable(entry, from_encoding, to_encoding)) {
3837 to_encoding = php_mb_get_encoding(to_enc_str, 1);
3844 bool order_significant =
true;
3851 order_significant =
false;
3853 if (php_mb_parse_encoding_array(from_enc_ht, &elist, &elistsz, 2) ==
FAILURE) {
3857 if (php_mb_parse_encoding_list(
ZSTR_VAL(from_enc_str),
ZSTR_LEN(from_enc_str), &elist, &elistsz, 0, 2) ==
FAILURE) {
3869 from_encoding = *elist;
3872 unsigned int num = 0;
3873 for (
size_t n = 0;
n < argc;
n++) {
3875 num += mb_recursive_count_strings(
zv);
3877 const unsigned char **val_list = (
const unsigned char**)
ecalloc(num,
sizeof(
char *));
3878 size_t *len_list = (
size_t*)
ecalloc(num,
sizeof(
size_t));
3880 for (
size_t n = 0;
n < argc;
n++) {
3882 if (mb_recursive_find_strings(
zv, val_list, len_list, &i)) {
3893 if (!from_encoding) {
3904 for (
size_t n = 0;
n < argc;
n++) {
3907 if (mb_recursive_convert_variable(
zv, from_encoding, to_encoding)) {
3919static uint32_t *make_conversion_map(
HashTable *target_hash,
size_t *conversion_map_size)
3923 size_t n_elems = *conversion_map_size = zend_hash_num_elements(target_hash);
3924 if (n_elems % 4 != 0) {
3929 uint32_t *convmap = (uint32_t*)
safe_emalloc(n_elems,
sizeof(uint32_t), 0);
3930 uint32_t *mapelm = convmap;
3946static bool html_numeric_entity_convert(uint32_t w, uint32_t *convmap,
size_t conversion_map_size, uint32_t *
retval)
3948 uint32_t *convmap_end = convmap + conversion_map_size;
3950 for (uint32_t *mapelm = convmap; mapelm < convmap_end; mapelm += 4) {
3951 uint32_t lo_code = mapelm[0];
3952 uint32_t hi_code = mapelm[1];
3953 uint32_t
offset = mapelm[2];
3954 uint32_t mask = mapelm[3];
3956 if (w >= lo_code && w <= hi_code) {
3972 uint32_t wchar_buf[32], converted_buf[32 * 13];
3973 unsigned char entity[16];
3975 unsigned int state = 0;
3976 unsigned char *
in = (
unsigned char*)
ZSTR_VAL(input);
3986 uint32_t *converted = converted_buf;
3990 for (
size_t i = 0; i < out_len; i++) {
3991 uint32_t w = wchar_buf[i];
3993 if (html_numeric_entity_convert(w, convmap, conversion_map_size, &w)) {
4004 unsigned char *
p = entity +
sizeof(entity);
4007 *(--
p) =
"0123456789ABCDEF"[w & 0xF];
4012 *(--
p) =
"0123456789"[w % 10];
4016 while (
p < entity +
sizeof(entity)) {
4017 *converted++ = *
p++;
4027 ZEND_ASSERT(converted <= converted_buf +
sizeof(converted_buf)/
sizeof(*converted_buf));
4038 size_t conversion_map_size;
4040 bool is_hex =
false;
4055 uint32_t *convmap = make_conversion_map(target_hash, &conversion_map_size);
4056 if (convmap ==
NULL) {
4060 RETVAL_STR(html_numeric_entity_encode(str,
enc, convmap, conversion_map_size, is_hex));
4065static bool html_numeric_entity_deconvert(uint32_t number, uint32_t *convmap,
size_t conversion_map_size, uint32_t *
retval)
4067 uint32_t *convmap_end = convmap + conversion_map_size;
4069 for (uint32_t *mapelm = convmap; mapelm < convmap_end; mapelm += 4) {
4070 uint32_t lo_code = mapelm[0];
4071 uint32_t hi_code = mapelm[1];
4072 uint32_t
offset = mapelm[2];
4073 uint32_t codepoint = number -
offset;
4074 if (codepoint >= lo_code && codepoint <= hi_code) {
4083#define DEC_ENTITY_MINLEN 3
4084#define HEX_ENTITY_MINLEN 4
4085#define DEC_ENTITY_MAXLEN 12
4086#define HEX_ENTITY_MAXLEN 11
4090 uint32_t wchar_buf[128], converted_buf[128];
4092 unsigned int state = 0;
4093 unsigned char *
in = (
unsigned char*)
ZSTR_VAL(input);
4116 unsigned int wchar_buf_offset = 0;
4120 size_t out_len =
encoding->to_wchar(&
in, &
in_len, wchar_buf + wchar_buf_offset, 127 - wchar_buf_offset, &
state);
4121 out_len += wchar_buf_offset;
4123 wchar_buf[out_len] =
'&';
4125 uint32_t *
p, *converted;
4129 if (wchar_buf_offset == 0) {
4133 if (
p == wchar_buf + out_len) {
4140 memcpy(converted_buf, wchar_buf, (
p - wchar_buf) * 4);
4141 converted = converted_buf + (
p - wchar_buf);
4144 converted = converted_buf;
4156 while ((w >=
'0' && w <=
'9') || (w >=
'A' && w <=
'F') || (w >=
'a' && w <=
'f'))
4163 wchar_buf_offset = p2 -
p;
4164 goto process_converted_wchars;
4167 memcpy(converted,
p, (p2 -
p) * 4);
4168 converted += p2 -
p;
4171 uint32_t
value = 0, *p3 =
p + 3;
4176 }
else if (w >=
'a') {
4182 if (html_numeric_entity_deconvert(
value, convmap, conversion_map_size, converted)) {
4187 memcpy(converted,
p, (p2 -
p) * 4);
4188 converted += p2 -
p;
4194 while (w >=
'0' && w <=
'9')
4200 wchar_buf_offset = p2 -
p;
4201 goto process_converted_wchars;
4204 memcpy(converted,
p, (p2 -
p) * 4);
4205 converted += p2 -
p;
4208 uint32_t
value = 0, *p3 =
p + 2;
4213 if (
value > 0x19999999) {
4214 memcpy(converted,
p, (p2 -
p) * 4);
4215 converted += p2 -
p;
4216 goto decimal_entity_too_big;
4220 if (html_numeric_entity_deconvert(
value, convmap, conversion_map_size, converted)) {
4225 memcpy(converted,
p, (p2 -
p) * 4);
4226 converted += p2 -
p;
4230 }
else if ((p2 == wchar_buf + out_len) &&
in_len) {
4233 wchar_buf_offset = 1;
4234 goto process_converted_wchars;
4238decimal_entity_too_big:
4247 memcpy(converted,
p, (p2 -
p) * 4);
4248 converted += p2 -
p;
4252 if (
p < wchar_buf + out_len)
4253 goto found_ampersand;
4257 wchar_buf_offset = 0;
4258process_converted_wchars:
4270 size_t conversion_map_size;
4285 uint32_t *convmap = make_conversion_map(target_hash, &conversion_map_size);
4286 if (convmap ==
NULL) {
4290 RETVAL_STR(html_numeric_entity_decode(str,
enc, convmap, conversion_map_size));
4298static int _php_mbstr_parse_mail_headers(
HashTable *
ht,
const char *str,
size_t str_len)
4303 int crlf_state = -1;
4305 size_t token_pos = 0;
4310 fld_name = fld_val =
NULL;
4326 if (crlf_state == 1) {
4331 if(token && token_pos > 0) {
4332 fld_name = zend_string_init(token, token_pos, 0);
4343 if (crlf_state == -1) {
4350 if (crlf_state == 1) {
4357 case ' ':
case '\t':
4358 if (crlf_state == -1) {
4367 if (crlf_state == 1) {
4386 if (crlf_state != -1) {
4396 if (crlf_state == -1) {
4397 if(token && token_pos > 0) {
4398 fld_val = zend_string_init(token, token_pos, 0);
4401 if (fld_name !=
NULL && fld_val !=
NULL) {
4411 fld_name = fld_val =
NULL;
4425 if (crlf_state == 1) {
4444 if(token && token_pos > 0) {
4445 fld_val = zend_string_init(token, token_pos, 0);
4447 if (fld_name !=
NULL && fld_val !=
NULL) {
4471 bool suppress_content_type =
false;
4472 bool suppress_content_transfer_encoding =
false;
4509 }
else if (headers_ht) {
4518 if (str_headers !=
NULL) {
4519 _php_mbstr_parse_mail_headers(&ht_headers,
ZSTR_VAL(str_headers),
ZSTR_LEN(str_headers));
4534 }
while (*
p ==
' ' || *
p ==
'\t');
4538 if (
strcasecmp(param_name,
"charset") == 0) {
4555 suppress_content_type =
true;
4558 if ((
s =
zend_hash_str_find(&ht_headers,
"content-transfer-encoding",
sizeof(
"content-transfer-encoding") - 1))) {
4567 body_enc = _body_enc;
4575 suppress_content_transfer_encoding =
true;
4581 for (; to_len; to_len--) {
4582 if (!isspace((
unsigned char) to_r[to_len - 1])) {
4585 to_r[to_len - 1] =
'\0';
4587 for (i = 0; to_r[i]; i++) {
4588 if (iscntrl((
unsigned char) to_r[i])) {
4592 if (to_r[i] ==
'\r' && to_r[i + 1] ==
'\n' && (to_r[i + 2] ==
' ' || to_r[i + 2] ==
'\t')) {
4594 while (to_r[i + 1] ==
' ' || to_r[i + 1] ==
'\t') {
4612 const char *line_sep =
PG(mail_mixed_lf_and_crlf) ?
"\n" :
CRLF;
4613 size_t line_sep_len =
strlen(line_sep);
4615 subject = mb_mime_header_encode(subject,
enc, tran_cs, head_enc == &
mbfl_encoding_base64, (
char*)line_sep, line_sep_len,
strlen(
"Subject: [PHP-jp nnnnnnnn]") + line_sep_len);
4623 unsigned int num_errors = 0;
4626 zend_string_free(tmpstr);
4630#define PHP_MBSTR_MAIL_MIME_HEADER1 "MIME-Version: 1.0"
4631#define PHP_MBSTR_MAIL_MIME_HEADER2 "Content-Type: text/plain"
4632#define PHP_MBSTR_MAIL_MIME_HEADER3 "; charset="
4633#define PHP_MBSTR_MAIL_MIME_HEADER4 "Content-Transfer-Encoding: "
4638 if (str_headers !=
NULL &&
ZSTR_LEN(str_headers) > 0) {
4647 smart_str_appendl(&str,
ZSTR_VAL(str_headers),
len);
4652 if (!zend_hash_str_exists(&ht_headers,
"mime-version",
sizeof(
"mime-version") - 1)) {
4654 smart_str_appendl(&str, line_sep, line_sep_len);
4660 if (!suppress_content_type) {
4662 smart_str_appendl(&str, line_sep, line_sep_len);
4669 smart_str_appends(&str,
p);
4674 if (!suppress_content_transfer_encoding) {
4676 smart_str_appendl(&str, line_sep, line_sep_len);
4683 smart_str_appends(&str,
p);
4686 str_headers = smart_str_extract(&str);
4689 if (force_extra_parameters) {
4691 }
else if (extra_cmd) {
4703 zend_string_release(subject);
4704 zend_string_free(conv);
4712#undef MAIL_ASCIIZ_CHECK_MBSTRING
4713#undef PHP_MBSTR_MAIL_MIME_HEADER1
4714#undef PHP_MBSTR_MAIL_MIME_HEADER2
4715#undef PHP_MBSTR_MAIL_MIME_HEADER3
4716#undef PHP_MBSTR_MAIL_MIME_HEADER4
4748 add_assoc_str(
return_value,
"http_output_conv_mimetypes",
4749 zend_ini_str(
"mbstring.http_output_conv_mimetypes",
sizeof(
"mbstring.http_output_conv_mimetypes") - 1, 0)
4764 add_assoc_string(
return_value,
"encoding_translation",
"On");
4766 add_assoc_string(
return_value,
"encoding_translation",
"Off");
4778 for (i = 0; i <
n; i++) {
4785 add_assoc_string(
return_value,
"substitute_character",
"none");
4787 add_assoc_string(
return_value,
"substitute_character",
"long");
4789 add_assoc_string(
return_value,
"substitute_character",
"entity");
4794 add_assoc_string(
return_value,
"strict_detection",
"On");
4796 add_assoc_string(
return_value,
"strict_detection",
"Off");
4812 "mbstring.http_output_conv_mimetypes",
4813 sizeof(
"mbstring.http_output_conv_mimetypes") - 1,
4844 for (i = 0; i <
n; i++) {
4874 uint32_t wchar_buf[128];
4875 unsigned char *
in = (
unsigned char*)input;
4876 unsigned int state = 0;
4885 size_t out_len =
encoding->to_wchar(&
in, &length, wchar_buf, 8, &
state);
4887 for (
unsigned int i = 0; i < out_len; i++) {
4896 for (
unsigned int i = 0; i < out_len; i++) {
4910#if defined(PHP_WIN32) && !defined(__clang__) && defined(_MSC_VER) && defined(_M_IX86)
4911# define MBSTRING_BROKEN_X86_MSVC_INTRINSICS
4915#ifndef ZEND_INTRIN_AVX2_NATIVE
4919static bool mb_fast_check_utf8_default(
zend_string *str)
4921 unsigned char *
p = (
unsigned char*)
ZSTR_VAL(str);
4927 unsigned char *e =
p + ((
ZSTR_LEN(str) + 1) & ~(
sizeof(__m128i) - 1));
4930 const __m128i over_f5 = _mm_set1_epi8(-117);
4932 const __m128i over_9f = _mm_set1_epi8(-97);
4934 const __m128i over_8f = _mm_set1_epi8(-113);
4936 const __m128i find_c0 = _mm_set1_epi8(-64);
4937 const __m128i c0_to_c1 = _mm_set1_epi8(-126);
4939 const __m128i find_e0 = _mm_set1_epi8(-32);
4940 const __m128i find_f0 = _mm_set1_epi8(-16);
4942 __m128i last_block = _mm_setzero_si128();
4946 operand = _mm_loadu_si128((__m128i*)
p);
4950 if (!_mm_movemask_epi8(operand)) {
4957 __m128i bad_mask = _mm_set_epi8(-64, -32, -16, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1);
4958 __m128i bad = _mm_cmpeq_epi8(_mm_and_si128(last_block, bad_mask), bad_mask);
4959 if (_mm_movemask_epi8(bad)) {
4965 p +=
sizeof(__m128i);
4967 goto finish_up_remaining_bytes;
4969 operand = _mm_loadu_si128((__m128i*)
p);
4970 if (_mm_movemask_epi8(operand)) {
4981 __m128i bad = _mm_cmplt_epi8(_mm_add_epi8(operand, over_f5), over_f5);
4989 __m128i operand2 = _mm_or_si128(_mm_slli_si128(operand, 1), _mm_srli_si128(last_block, 15));
4990 __m128i mask1 = _mm_or_si128(find_e0, _mm_and_si128(_mm_set1_epi8(0xD), _mm_cmpgt_epi8(operand, over_9f)));
4991 bad = _mm_or_si128(bad, _mm_cmpeq_epi8(operand2, mask1));
4997 __m128i mask2 = _mm_or_si128(find_f0, _mm_and_si128(_mm_set1_epi8(0x4), _mm_cmpgt_epi8(operand, over_8f)));
4998 bad = _mm_or_si128(bad, _mm_cmpeq_epi8(operand2, mask2));
5004 bad = _mm_or_si128(bad, _mm_cmplt_epi8(_mm_add_epi8(operand, find_c0), c0_to_c1));
5013 __m128i cont_mask = _mm_cmpeq_epi8(_mm_and_si128(operand2, find_c0), find_c0);
5014 __m128i operand3 = _mm_or_si128(_mm_slli_si128(operand, 2), _mm_srli_si128(last_block, 14));
5015 cont_mask = _mm_or_si128(cont_mask, _mm_cmpeq_epi8(_mm_and_si128(operand3, find_e0), find_e0));
5016 __m128i operand4 = _mm_or_si128(_mm_slli_si128(operand, 3), _mm_srli_si128(last_block, 13));
5017 cont_mask = _mm_or_si128(cont_mask, _mm_cmpeq_epi8(_mm_and_si128(operand4, find_f0), find_f0));
5024 __m128i continuation = _mm_cmplt_epi8(operand, find_c0);
5025 bad = _mm_or_si128(bad, _mm_xor_si128(continuation, cont_mask));
5029 if (_mm_movemask_epi8(bad)) {
5033 last_block = operand;
5034 p +=
sizeof(__m128i);
5037finish_up_remaining_bytes:
5040 uint8_t remaining_bytes =
ZSTR_LEN(str) & (
sizeof(__m128i) - 1);
5058 switch (remaining_bytes) {
5060 __m128i bad_mask = _mm_set_epi8(-64, -32, -16, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1);
5061 __m128i bad = _mm_cmpeq_epi8(_mm_and_si128(last_block, bad_mask), bad_mask);
5062 return _mm_movemask_epi8(bad) == 0;
5065 operand = _mm_set_epi16(0, 0, 0, 0, 0, 0, 0, *((uint16_t*)
p));
5069 operand = _mm_set_epi32(0, 0, 0, *((uint32_t*)
p));
5072 operand = _mm_srli_si128(_mm_loadu_si128((__m128i*)(
p - 10)), 10);
5075 operand = _mm_srli_si128(_mm_loadu_si128((__m128i*)(
p - 9)), 9);
5079#ifdef MBSTRING_BROKEN_X86_MSVC_INTRINSICS
5080 operand = _mm_set_epi32(0, 0, ((int32_t*)
p)[1], ((int32_t*)
p)[0]);
5082 operand = _mm_set_epi64x(0, *((uint64_t*)
p));
5086 operand = _mm_srli_si128(_mm_loadu_si128((__m128i*)(
p - 6)), 6);
5089 operand = _mm_srli_si128(_mm_loadu_si128((__m128i*)(
p - 5)), 5);
5092 operand = _mm_srli_si128(_mm_loadu_si128((__m128i*)(
p - 4)), 4);
5095 operand = _mm_srli_si128(_mm_loadu_si128((__m128i*)(
p - 3)), 3);
5098 operand = _mm_srli_si128(_mm_loadu_si128((__m128i*)(
p - 2)), 2);
5101 operand = _mm_srli_si128(_mm_loadu_si128((__m128i*)(
p - 1)), 1);
5119 static const uint8_t utf8_table[] = {
5120 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
5121 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
5122 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
5126 for (; length > 0;
p++) {
5128 unsigned char c = *
p;
5145 uint32_t ab = utf8_table[c & 0x3f];
5153 if (((d = *(++
p)) & 0xc0) != 0x80) {
5164 if ((c & 0x3e) == 0) {
5172 if ((*(++
p) & 0xc0) != 0x80 || (c == 0xe0 && (d & 0x20) == 0) || (c == 0xed && d >= 0xa0)) {
5181 if ((*(++
p) & 0xc0) != 0x80 || (*(++
p) & 0xc0) != 0x80 || (c == 0xf0 && (d & 0x30) == 0) || (c > 0xf4 || (c == 0xf4 && d > 0x8f))) {
5196#ifdef ZEND_INTRIN_AVX2_NATIVE
5199# include <immintrin.h>
5200# define mb_fast_check_utf8 mb_fast_check_utf8_avx2
5202#elif defined(ZEND_INTRIN_AVX2_RESOLVER)
5206# include <immintrin.h>
5209# ifdef ZEND_INTRIN_AVX2_FUNC_PROTO
5221static check_utf8_func_t resolve_check_utf8(
void)
5223 if (zend_cpu_supports_avx2()) {
5224 return mb_fast_check_utf8_avx2;
5226 return mb_fast_check_utf8_default;
5235#ifdef HAVE_FUNC_ATTRIBUTE_TARGET
5238static bool mb_fast_check_utf8_avx2(
zend_string *str);
5245 return check_utf8_ptr(str);
5248static void init_check_utf8(
void)
5250 if (zend_cpu_supports_avx2()) {
5251 check_utf8_ptr = mb_fast_check_utf8_avx2;
5253 check_utf8_ptr = mb_fast_check_utf8_default;
5261#define mb_fast_check_utf8 mb_fast_check_utf8_default
5265#if defined(ZEND_INTRIN_AVX2_NATIVE) || defined(ZEND_INTRIN_AVX2_RESOLVER)
5269#if defined(__GNUC__) && !defined(__llvm__) && !defined(__INTEL_COMPILER) && __GNUC__ < 8
5270# define _mm256_set_m128i(v0, v1) _mm256_insertf128_si256(_mm256_castsi128_si256(v1), (v0), 1)
5286#define _mm256_shift_epi8(hi, lo, shift) _mm256_alignr_epi8(lo, _mm256_permute2x128_si256(hi, lo, 33), 16 - shift)
5293#ifdef ZEND_INTRIN_AVX2_FUNC_PROTO
5296static bool mb_fast_check_utf8_avx2(
zend_string *str)
5299 unsigned char *
p = (
unsigned char*)
ZSTR_VAL(str);
5300 unsigned char *e =
p + ((
ZSTR_LEN(str) + 1) & ~(
sizeof(__m256i) - 1));
5332#define OVERLONG_2BYTE 0x2
5333#define _1BYTE (BAD_BYTE | OVERLONG_2BYTE)
5334#define OVERLONG_3BYTE 0x4
5335#define SURROGATE 0x8
5336#define OVERLONG_4BYTE 0x10
5337#define INVALID_CP 0x20
5346 const __m256i bad_hi_nibble2 = _mm256_set_epi8(
5347 BAD_BYTE | OVERLONG_4BYTE | INVALID_CP, OVERLONG_3BYTE | SURROGATE, 0, OVERLONG_2BYTE,
5351 BAD_BYTE | OVERLONG_4BYTE | INVALID_CP, OVERLONG_3BYTE | SURROGATE, 0, OVERLONG_2BYTE,
5355 const __m256i bad_lo_nibble2 = _mm256_set_epi8(
5356 BAD_BYTE, BAD_BYTE, BAD_BYTE | SURROGATE, BAD_BYTE,
5357 BAD_BYTE, BAD_BYTE, BAD_BYTE, BAD_BYTE,
5358 BAD_BYTE, BAD_BYTE, BAD_BYTE, INVALID_CP,
5359 0, 0, OVERLONG_2BYTE, OVERLONG_2BYTE | OVERLONG_3BYTE | OVERLONG_4BYTE,
5360 BAD_BYTE, BAD_BYTE, BAD_BYTE | SURROGATE, BAD_BYTE,
5361 BAD_BYTE, BAD_BYTE, BAD_BYTE, BAD_BYTE,
5362 BAD_BYTE, BAD_BYTE, BAD_BYTE, INVALID_CP,
5363 0, 0, OVERLONG_2BYTE, OVERLONG_2BYTE | OVERLONG_3BYTE | OVERLONG_4BYTE);
5364 const __m256i bad_hi_nibble = _mm256_set_epi8(
5365 _1BYTE | SURROGATE | INVALID_CP, _1BYTE | SURROGATE | INVALID_CP,
5366 _1BYTE | SURROGATE | INVALID_CP, _1BYTE | SURROGATE | INVALID_CP,
5367 _1BYTE | SURROGATE | INVALID_CP, _1BYTE | SURROGATE | INVALID_CP,
5368 _1BYTE | OVERLONG_3BYTE | INVALID_CP, _1BYTE | OVERLONG_3BYTE | OVERLONG_4BYTE,
5369 _1BYTE | OVERLONG_3BYTE | OVERLONG_4BYTE, _1BYTE | OVERLONG_3BYTE | OVERLONG_4BYTE,
5370 _1BYTE | OVERLONG_3BYTE | OVERLONG_4BYTE, _1BYTE | OVERLONG_3BYTE | OVERLONG_4BYTE,
5371 _1BYTE | OVERLONG_3BYTE | OVERLONG_4BYTE, _1BYTE | OVERLONG_3BYTE | OVERLONG_4BYTE,
5372 _1BYTE | OVERLONG_3BYTE | OVERLONG_4BYTE, _1BYTE | OVERLONG_3BYTE | OVERLONG_4BYTE,
5373 _1BYTE | SURROGATE | INVALID_CP, _1BYTE | SURROGATE | INVALID_CP,
5374 _1BYTE | SURROGATE | INVALID_CP, _1BYTE | SURROGATE | INVALID_CP,
5375 _1BYTE | SURROGATE | INVALID_CP, _1BYTE | SURROGATE | INVALID_CP,
5376 _1BYTE | OVERLONG_3BYTE | INVALID_CP, _1BYTE | OVERLONG_3BYTE | OVERLONG_4BYTE,
5377 _1BYTE | OVERLONG_3BYTE | OVERLONG_4BYTE, _1BYTE | OVERLONG_3BYTE | OVERLONG_4BYTE,
5378 _1BYTE | OVERLONG_3BYTE | OVERLONG_4BYTE, _1BYTE | OVERLONG_3BYTE | OVERLONG_4BYTE,
5379 _1BYTE | OVERLONG_3BYTE | OVERLONG_4BYTE, _1BYTE | OVERLONG_3BYTE | OVERLONG_4BYTE,
5380 _1BYTE | OVERLONG_3BYTE | OVERLONG_4BYTE, _1BYTE | OVERLONG_3BYTE | OVERLONG_4BYTE);
5382 const __m256i find_continuation = _mm256_set1_epi8(-64);
5383 const __m256i _b = _mm256_set1_epi8(0xB);
5384 const __m256i _d = _mm256_set1_epi8(0xD);
5385 const __m256i _f = _mm256_set1_epi8(0xF);
5387 __m256i last_hi_nibbles = _mm256_setzero_si256(), last_lo_nibbles = _mm256_setzero_si256();
5391 operand = _mm256_loadu_si256((__m256i*)
p);
5394 if (!_mm256_movemask_epi8(operand)) {
5398 __m256i bad_mask = _mm256_set_epi8(0xB, 0xD, 0xE, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127);
5399 __m256i bad = _mm256_cmpgt_epi8(last_hi_nibbles, bad_mask);
5400 if (_mm256_movemask_epi8(bad)) {
5406 p +=
sizeof(__m256i);
5408 goto finish_up_remaining_bytes;
5410 operand = _mm256_loadu_si256((__m256i*)
p);
5411 if (_mm256_movemask_epi8(operand)) {
5417 __m256i hi_nibbles = _mm256_and_si256(_mm256_srli_epi16(operand, 4), _f);
5418 __m256i lo_nibbles = _mm256_and_si256(operand, _f);
5420 __m256i lo_nibbles2 = _mm256_shift_epi8(last_lo_nibbles, lo_nibbles, 1);
5421 __m256i hi_nibbles2 = _mm256_shift_epi8(last_hi_nibbles, hi_nibbles, 1);
5424 __m256i bad = _mm256_cmpgt_epi8(
5427 _mm256_shuffle_epi8(bad_lo_nibble2, lo_nibbles2),
5428 _mm256_shuffle_epi8(bad_hi_nibble2, hi_nibbles2)),
5429 _mm256_shuffle_epi8(bad_hi_nibble, hi_nibbles)),
5430 _mm256_setzero_si256());
5432 __m256i cont_mask = _mm256_cmpgt_epi8(hi_nibbles2, _b);
5433 __m256i hi_nibbles3 = _mm256_shift_epi8(last_hi_nibbles, hi_nibbles, 2);
5434 cont_mask = _mm256_or_si256(cont_mask, _mm256_cmpgt_epi8(hi_nibbles3, _d));
5435 __m256i hi_nibbles4 = _mm256_shift_epi8(last_hi_nibbles, hi_nibbles, 3);
5436 cont_mask = _mm256_or_si256(cont_mask, _mm256_cmpeq_epi8(hi_nibbles4, _f));
5438 __m256i continuation = _mm256_cmpgt_epi8(find_continuation, operand);
5439 bad = _mm256_or_si256(bad, _mm256_xor_si256(continuation, cont_mask));
5441 if (_mm256_movemask_epi8(bad)) {
5445 last_hi_nibbles = hi_nibbles;
5446 last_lo_nibbles = lo_nibbles;
5447 p +=
sizeof(__m256i);
5450finish_up_remaining_bytes:
5452 uint8_t remaining_bytes =
ZSTR_LEN(str) & (
sizeof(__m256i) - 1);
5454 switch (remaining_bytes) {
5457 __m256i bad_mask = _mm256_set_epi8(0xB, 0xD, 0xE, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127);
5458 __m256i bad = _mm256_cmpgt_epi8(last_hi_nibbles, bad_mask);
5459 return _mm256_movemask_epi8(bad) == 0;
5462 operand = _mm256_set_epi16(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, *((int16_t*)
p));
5466 operand = _mm256_set_epi32(0, 0, 0, 0, 0, 0, 0, *((int32_t*)
p));
5469 operand = _mm256_set_m128i(_mm_setzero_si128(), _mm_srli_si128(_mm_loadu_si128((__m128i*)(
p - 10)), 10));
5472 operand = _mm256_set_m128i(_mm_setzero_si128(), _mm_srli_si128(_mm_loadu_si128((__m128i*)(
p - 9)), 9));
5476#ifdef MBSTRING_BROKEN_X86_MSVC_INTRINSICS
5477 operand = _mm256_set_epi32(0, 0, 0, 0, 0, 0, ((int32_t*)
p)[1], ((int32_t*)
p)[0]);
5479 operand = _mm256_set_epi64x(0, 0, 0, *((int64_t*)
p));
5483 operand = _mm256_set_m128i(_mm_setzero_si128(), _mm_srli_si128(_mm_loadu_si128((__m128i*)(
p - 6)), 6));
5486 operand = _mm256_set_m128i(_mm_setzero_si128(), _mm_srli_si128(_mm_loadu_si128((__m128i*)(
p - 5)), 5));
5489 operand = _mm256_set_m128i(_mm_setzero_si128(), _mm_srli_si128(_mm_loadu_si128((__m128i*)(
p - 4)), 4));
5492 operand = _mm256_set_m128i(_mm_setzero_si128(), _mm_srli_si128(_mm_loadu_si128((__m128i*)(
p - 3)), 3));
5495 operand = _mm256_set_m128i(_mm_setzero_si128(), _mm_srli_si128(_mm_loadu_si128((__m128i*)(
p - 2)), 2));
5498 operand = _mm256_set_m128i(_mm_setzero_si128(), _mm_srli_si128(_mm_loadu_si128((__m128i*)(
p - 1)), 1));
5502 operand = _mm256_set_m128i(_mm_setzero_si128(), _mm_loadu_si128((__m128i*)
p));
5505 operand = _mm256_set_m128i(_mm_srli_si128(_mm_loadu_si128((__m128i*)(
p + 2)), 14), _mm_loadu_si128((__m128i*)
p));
5508 operand = _mm256_set_m128i(_mm_srli_si128(_mm_loadu_si128((__m128i*)(
p + 3)), 13), _mm_loadu_si128((__m128i*)
p));
5511 operand = _mm256_set_m128i(_mm_srli_si128(_mm_loadu_si128((__m128i*)(
p + 4)), 12), _mm_loadu_si128((__m128i*)
p));
5514 operand = _mm256_set_m128i(_mm_srli_si128(_mm_loadu_si128((__m128i*)(
p + 5)), 11), _mm_loadu_si128((__m128i*)
p));
5517 operand = _mm256_set_m128i(_mm_srli_si128(_mm_loadu_si128((__m128i*)(
p + 6)), 10), _mm_loadu_si128((__m128i*)
p));
5520 operand = _mm256_set_m128i(_mm_srli_si128(_mm_loadu_si128((__m128i*)(
p + 7)), 9), _mm_loadu_si128((__m128i*)
p));
5523 operand = _mm256_set_m128i(_mm_srli_si128(_mm_loadu_si128((__m128i*)(
p + 8)), 8), _mm_loadu_si128((__m128i*)
p));
5526 operand = _mm256_set_m128i(_mm_srli_si128(_mm_loadu_si128((__m128i*)(
p + 9)), 7), _mm_loadu_si128((__m128i*)
p));
5529 operand = _mm256_set_m128i(_mm_srli_si128(_mm_loadu_si128((__m128i*)(
p + 10)), 6), _mm_loadu_si128((__m128i*)
p));
5532 operand = _mm256_set_m128i(_mm_srli_si128(_mm_loadu_si128((__m128i*)(
p + 11)), 5), _mm_loadu_si128((__m128i*)
p));
5535 operand = _mm256_set_m128i(_mm_srli_si128(_mm_loadu_si128((__m128i*)(
p + 12)), 4), _mm_loadu_si128((__m128i*)
p));
5538 operand = _mm256_set_m128i(_mm_srli_si128(_mm_loadu_si128((__m128i*)(
p + 13)), 3), _mm_loadu_si128((__m128i*)
p));
5541 operand = _mm256_set_m128i(_mm_srli_si128(_mm_loadu_si128((__m128i*)(
p + 14)), 2), _mm_loadu_si128((__m128i*)
p));
5544 operand = _mm256_set_m128i(_mm_srli_si128(_mm_loadu_si128((__m128i*)(
p + 15)), 1), _mm_loadu_si128((__m128i*)
p));
5645 }
else if (input_str) {
5649 "Calling mb_check_encoding() without argument is deprecated");
5658 const uint32_t enc_name_arg_num)
5665 enc = php_mb_get_encoding(enc_name, enc_name_arg_num);
5671 if (php_mb_is_unsupported_no_encoding(no_enc)) {
5679 unsigned int state = 0;
5686 return wchar_buf[0];
5708 cp = php_mb_ord(str, str_len,
enc, 2);
5728 enc = php_mb_get_encoding(enc_name, enc_name_arg_num);
5734 if (php_mb_is_unsupported_no_encoding(no_enc)) {
5739 if (cp < 0 || cp > 0x10ffff) {
5743 if (php_mb_is_no_encoding_utf8(no_enc)) {
5744 if (
cp > 0xd7ff && 0xe000 >
cp) {
5750 }
else if (
cp < 0x800) {
5751 ret = zend_string_alloc(2, 0);
5755 }
else if (
cp < 0x10000) {
5756 ret = zend_string_alloc(3, 0);
5762 ret = zend_string_alloc(4, 0);
5773 buf[0] = (
cp >> 24) & 0xff;
5774 buf[1] = (
cp >> 16) & 0xff;
5775 buf[2] = (
cp >> 8) & 0xff;
5783 zend_string_release(
ret);
5832 size_t input_length = mb_get_strlen(input,
encoding);
5836 if (pad_to_length < 0 || (
size_t)pad_to_length <= input_length) {
5850 size_t pad_length = mb_get_strlen(pad,
encoding);
5852 size_t num_mb_pad_chars = pad_to_length - input_length;
5855 size_t left_pad = 0, right_pad = 0;
5856 switch (pad_type_val) {
5858 right_pad = num_mb_pad_chars;
5862 left_pad = num_mb_pad_chars;
5866 left_pad = num_mb_pad_chars / 2;
5867 right_pad = num_mb_pad_chars - left_pad;
5872 size_t full_left_pad_copies = left_pad / pad_length;
5873 size_t full_right_pad_copies = right_pad / pad_length;
5874 size_t remaining_left_pad_chars = left_pad % pad_length;
5875 size_t remaining_right_pad_chars = right_pad % pad_length;
5878 goto overflow_no_release;
5882 size_t full_left_pad_bytes = full_left_pad_copies *
ZSTR_LEN(pad);
5883 size_t full_right_pad_bytes = full_right_pad_copies *
ZSTR_LEN(pad);
5887 zend_string *remaining_left_pad_str = mb_get_substr(pad, 0, remaining_left_pad_chars,
encoding);
5888 zend_string *remaining_right_pad_str = mb_get_substr(pad, 0, remaining_right_pad_chars,
encoding);
5895 size_t left_pad_bytes = full_left_pad_bytes +
ZSTR_LEN(remaining_left_pad_str);
5896 size_t right_pad_bytes = full_right_pad_bytes +
ZSTR_LEN(remaining_right_pad_str);
5907 for (
size_t i = 0; i < full_left_pad_copies; i++,
buffer +=
ZSTR_LEN(pad)) {
5918 for (
size_t i = 0; i < full_right_pad_copies; i++,
buffer +=
ZSTR_LEN(pad)) {
5964static void php_mb_populate_current_detect_order_list(
void)
5978 for (i = 0; i < nentries; i++) {
5988static int php_mb_encoding_translation(
void)
6015 if (nbytes == (
size_t)-1) {
6018 while (*
p !=
'\0') {
6020 if ((
unsigned char)*
p == (
unsigned char)c) {
6032 size_t bcnt = nbytes;
6035 if ((
unsigned char)*
p == (
unsigned char)c) {
6039 if (bcnt < nbytes_char) {
6043 bcnt -= nbytes_char;
6058 zend_string_free(haystack_conv);
6059 zend_string_free(needle_conv);
6064static void php_mb_gpc_get_detect_order(
const zend_encoding ***list,
size_t *list_size)
6077static const unsigned char base64_table[] = {
6079 0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,
6081 0x4e,0x4f,0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,
6083 0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,
6085 0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,
6087 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x2b,0x2f,0x00
6090static size_t transfer_encoded_size(
mb_convert_buf *tmpbuf,
bool base64)
6093 return ((mb_convert_buf_len(tmpbuf) + 2) / 3) * 4;
6095 size_t enc_size = 0;
6096 unsigned char *
p = (
unsigned char*)
ZSTR_VAL(tmpbuf->
str);
6098 unsigned char c = *
p++;
6099 enc_size += (c > 0x7F || c ==
'=' || mime_char_needs_qencode[c]) ? 3 : 1;
6107 unsigned char *
out, *limit;
6109 unsigned char *
p = (
unsigned char*)
ZSTR_VAL(tmpbuf->
str), *e = tmpbuf->
out;
6113 while ((e -
p) >= 3) {
6114 unsigned char a = *
p++;
6115 unsigned char b = *
p++;
6116 unsigned char c = *
p++;
6117 uint32_t bits = (
a << 16) | (b << 8) | c;
6118 out = mb_convert_buf_add4(
out,
6119 base64_table[(bits >> 18) & 0x3F],
6120 base64_table[(bits >> 12) & 0x3F],
6121 base64_table[(bits >> 6) & 0x3F],
6122 base64_table[bits & 0x3F]);
6126 uint32_t bits = *
p++;
6127 out = mb_convert_buf_add4(
out, base64_table[(bits >> 2) & 0x3F], base64_table[(bits & 0x3) << 4],
'=',
'=');
6129 unsigned char a = *
p++;
6130 unsigned char b = *
p++;
6131 uint32_t bits = (
a << 8) | b;
6132 out = mb_convert_buf_add4(
out, base64_table[(bits >> 10) & 0x3F], base64_table[(bits >> 4) & 0x3F], base64_table[(bits & 0xF) << 2],
'=');
6138 unsigned char c = *
p++;
6139 if (c > 0x7F || c ==
'=' || mime_char_needs_qencode[c]) {
6140 out = mb_convert_buf_add3(
out,
'=',
"0123456789ABCDEF"[(c >> 4) & 0xF],
"0123456789ABCDEF"[c & 0xF]);
6142 out = mb_convert_buf_add(
out, c);
6147 mb_convert_buf_reset(tmpbuf, 0);
6151#define MBSTRING_HEADER_ENC_WCHAR_BUFSIZE 90
6155 unsigned char *
in = (
unsigned char*)
ZSTR_VAL(input);
6165 if (indent < 0 || indent >= 74) {
6169 if (linefeed_len > 8) {
6173 for (
size_t i = 0; i < linefeed_len; i++) {
6174 if (linefeed[i] ==
'\0') {
6180 unsigned int state = 0;
6188 size_t line_start = 0;
6192 bool checking_leading_spaces =
true;
6196 e = wchar_buf + out_len;
6200 if (checking_leading_spaces) {
6204 checking_leading_spaces =
false;
6207 if (w < 0x21 || w > 0x7E || w ==
'=' || w ==
'?' || w ==
'_') {
6211 goto no_passthrough;
6216 return zend_string_copy(input);
6232 e = wchar_buf +
offset + out_len;
6236 uint32_t *word_start =
p;
6239 while (
p < e && *
p ==
' ' && (
p - word_start) <= 74) {
6246 if (w < 0x20 || w > 0x7E || w ==
'?' || w ==
'=' || w ==
'_' || (w ==
' ' && (
p - word_start) > 74)) {
6251feed_and_mime_encode:
6252 if (mb_convert_buf_len(&
buf) - line_start + indent +
strlen(outcode->
mime_name) > 55) {
6254 buf.out = mb_convert_buf_appendn(
buf.out, linefeed, linefeed_len);
6255 buf.out = mb_convert_buf_add(
buf.out,
' ');
6257 line_start = mb_convert_buf_len(&
buf);
6258 }
else if (mb_convert_buf_len(&
buf) > 0) {
6260 buf.out = mb_convert_buf_add(
buf.out,
' ');
6263 goto mime_encoding_needed;
6264 }
else if (w ==
' ') {
6266 if (mb_convert_buf_len(&
buf) - line_start + (
p - word_start) + indent > 75) {
6268 buf.out = mb_convert_buf_appendn(
buf.out, linefeed, linefeed_len);
6269 buf.out = mb_convert_buf_add(
buf.out,
' ');
6271 line_start = mb_convert_buf_len(&
buf);
6272 }
else if (mb_convert_buf_len(&
buf) > 0) {
6274 buf.out = mb_convert_buf_add(
buf.out,
' ');
6277 while (word_start <
p-1) {
6278 buf.out = mb_convert_buf_add(
buf.out, *word_start++ & 0xFF);
6281 while (
p < e && *
p ==
' ') {
6294 goto feed_and_mime_encode;
6303 if (word_start < e && mb_convert_buf_len(&
buf) > 0) {
6307 if (mb_convert_buf_len(&
buf) - line_start + (
p - word_start) + indent > 74) {
6309 buf.out = mb_convert_buf_appendn(
buf.out, linefeed, linefeed_len);
6310 buf.out = mb_convert_buf_add(
buf.out,
' ');
6313 buf.out = mb_convert_buf_add(
buf.out,
' ');
6316 while (word_start < e) {
6317 buf.out = mb_convert_buf_add(
buf.out, *word_start++ & 0xFF);
6325mime_encoding_needed: ;
6339 goto start_new_line;
6349 e = wchar_buf +
offset + out_len;
6353 buf.out = mb_convert_buf_add2(
buf.out,
'=',
'?');
6355 buf.out = mb_convert_buf_add3(
buf.out,
'?', base64 ?
'B' :
'Q',
'?');
6360 unsigned int n = 12;
6361 size_t space_available = 73 - indent - (mb_convert_buf_len(&
buf) - line_start);
6368 size_t tmppos = mb_convert_buf_len(&tmpbuf);
6369 unsigned int tmpstate = tmpbuf.
state;
6380 size_t tmppos2 = mb_convert_buf_len(&tmpbuf);
6381 unsigned int tmpstate2 = tmpbuf.
state;
6384 if (transfer_encoded_size(&tmpbuf, base64) <= space_available || (
n == 1 && tmppos == 0)) {
6393 transfer_encode_mime_bytes(&tmpbuf, &
buf, base64);
6395 buf.out = mb_convert_buf_add2(
buf.out,
'?',
'=');
6396 mb_convert_buf_free(&tmpbuf);
6401 mb_convert_buf_reset(&tmpbuf, tmppos2);
6402 tmpbuf.
state = tmpstate2;
6407 mb_convert_buf_reset(&tmpbuf, tmppos);
6408 tmpbuf.
state = tmpstate;
6414 transfer_encode_mime_bytes(&tmpbuf, &
buf, base64);
6418 buf.out = mb_convert_buf_add2(
buf.out,
'?',
'=');
6424 buf.out = mb_convert_buf_appendn(
buf.out, linefeed, linefeed_len);
6425 buf.out = mb_convert_buf_add(
buf.out,
' ');
6426 line_start = mb_convert_buf_len(&
buf);
6432 goto refill_wchar_buf;
6434 goto start_new_line;
6437 mb_convert_buf_free(&tmpbuf);
6453 char *linefeed =
"\r\n";
6454 size_t linefeed_len = 2;
6467 if (charset_name !=
NULL) {
6468 charset = php_mb_get_encoding(charset_name, 2);
6480 char t = transenc->
name[0];
6481 if (t ==
'Q' || t ==
'q') {
6487 if (transenc_name !=
NULL &&
ZSTR_LEN(transenc_name) > 0) {
6488 char t =
ZSTR_VAL(transenc_name)[0];
6489 if (t ==
'Q' || t ==
'q') {
6497static int8_t decode_base64(
unsigned char c)
6499 if (c >=
'A' && c <=
'Z') {
6501 }
else if (c >=
'a' && c <=
'z') {
6502 return c -
'a' + 26;
6503 }
else if (c >=
'0' && c <=
'9') {
6504 return c -
'0' + 52;
6505 }
else if (c ==
'+') {
6507 }
else if (c ==
'/') {
6513static int8_t qprint_map[] = {
6514 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
6515 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
6516 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
6517 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1,
6518 -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
6519 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
6520 -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
6521 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
6522 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
6523 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
6524 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
6525 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
6526 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
6527 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
6528 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
6529 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
6533static unsigned char* mime_header_decode_encoded_word(
unsigned char *
p,
unsigned char *e,
const mbfl_encoding *outcode,
mb_convert_buf *outbuf,
unsigned int *
state)
6545 if (charset_end ==
NULL) {
6549 unsigned char *
encoding = charset_end + 1;
6551 if (
p >= e || *
p++ !=
'?') {
6557 efree(charset_name);
6558 if (incode ==
NULL) {
6562 unsigned char *end_marker = (
unsigned char*)zend_memnstr((
const char*)
p,
"?=", 2, (
const char*)e);
6565 }
else if (
p < e && *(e-1) ==
'?') {
6575 unsigned char c = *
p++;
6579 }
else if (c ==
'=' && (e -
p) >= 2) {
6580 unsigned char c2 = *
p++;
6581 unsigned char c3 = *
p++;
6582 if (qprint_map[c2] >= 0 && qprint_map[c3] >= 0) {
6583 *bufp++ = (qprint_map[c2] << 4) | (qprint_map[c3] & 0xF);
6585 }
else if (c2 ==
'\r') {
6590 }
else if (c2 ==
'\n') {
6599 unsigned int bits = 0, cache = 0;
6601 unsigned char c = *
p++;
6602 if (c ==
'\r' || c ==
'\n' || c ==
' ' || c ==
'\t' || c ==
'=') {
6605 int8_t decoded = decode_base64(c);
6606 if (decoded == -1) {
6611 cache = (cache << 6) | (decoded & 0x3F);
6613 *bufp++ = (cache >> 16) & 0xFF;
6614 *bufp++ = (cache >> 8) & 0xFF;
6615 *bufp++ = cache & 0xFF;
6620 *bufp++ = (cache >> 10) & 0xFF;
6621 *bufp++ = (cache >> 2) & 0xFF;
6622 }
else if (bits == 12) {
6623 *bufp++ = (cache >> 4) & 0xFF;
6631 uint32_t wchar_buf[128];
6637 outcode->
from_wchar(wchar_buf, out_len, outbuf,
false);
6647 unsigned int state = 0;
6648 bool space_pending =
false;
6654 unsigned char c = *
p;
6656 if (c ==
'=' && *(
p + 1) ==
'?' && (e -
p) >= 6) {
6658 unsigned char *incode_end = memchr(
p + 2,
'?', e -
p - 2);
6659 if (incode_end && (e - incode_end) >= 3) {
6660 unsigned char *temp = mime_header_decode_encoded_word(
p, e, outcode, &
buf, &
state);
6665 if (
p < e && (*
p ==
'\n' || *
p ==
'\r')) {
6668 }
while (
p < e && (*
p ==
'\n' || *
p ==
'\r' || *
p ==
'\t' || *
p ==
' '));
6671 space_pending =
true;
6678 if (space_pending) {
6679 uint32_t space =
' ';
6681 space_pending =
false;
6685 if (c !=
'\n' && c !=
'\r') {
6686 unsigned char *
end =
p + 1;
6687 while (
end < e && (*
end !=
'=' && *
end !=
'\n' && *
end !=
'\r')) {
6690 uint32_t wchar_buf[128];
6699 if (
p < e && (*
p ==
'\n' || *
p ==
'\r')) {
6702 }
while (
p < e && (*
p ==
'\n' || *
p ==
'\r' || *
p ==
'\t' || *
p ==
' '));
6707 uint32_t space =
' ';
6715 return mb_convert_buf_result(&
buf, outcode);
SAPI_API int sapi_register_treat_data(void(*treat_data)(int arg, char *str, zval *destArray))
SAPI_API void sapi_unregister_post_entry(const sapi_post_entry *post_entry)
SAPI_API int sapi_register_post_entries(const sapi_post_entry *post_entries)
#define SAPI_DEFAULT_MIMETYPE
#define sapi_add_header(a, b, c)
struct _sapi_post_entry sapi_post_entry
count(Countable|array $value, int $mode=COUNT_NORMAL)
strchr(string $haystack, string $needle, bool $before_needle=false)
#define FIRST_DOUBLEWIDTH_CODEPOINT
PHPAPI zend_string * php_escape_shell_cmd(const zend_string *unescaped_cmd)
zend_ffi_ctype_name_buf buf
foreach($dp as $el) foreach( $dp as $el) if( $pass2< 2) echo ""
enum entity_charset charset
PHPAPI ZEND_COLD void php_info_print_table_header(int num_cols,...)
PHPAPI bool php_mail(const char *to, const char *subject, const char *message, const char *headers, const char *extra_cmd)
PHPAPI zend_string * php_mail_build_headers(HashTable *headers)
PHPAPI void(* php_internal_encoding_changed)(void)
PHPAPI const char * php_get_output_encoding(void)
PHPAPI const char * php_get_input_encoding(void)
PHPAPI ZEND_COLD void php_error_docref(const char *docref, int type, const char *format,...)
PHPAPI const char * php_get_internal_encoding(void)
const mbfl_encoding * _php_mb_encoding_handler_ex(const php_mb_encoding_handler_info_t *info, zval *array_ptr, char *res)
struct _php_mb_encoding_handler_info_t php_mb_encoding_handler_info_t
mbfl_string * mbfl_strcut(mbfl_string *string, mbfl_string *result, size_t from, size_t length)
#define MBFL_ERROR_OFFSET
#define MBFL_OUTPUTFILTER_ILLEGAL_MODE_LONG
#define MBFL_ERROR_ENCODING
#define MBFL_SUBSTR_UNTIL_END
#define MBFL_VERSION_MAJOR
#define MBFL_VERSION_TEENY
#define MBFL_OUTPUTFILTER_ILLEGAL_MODE_BADUTF8
#define MBFL_ERROR_NOT_FOUND
#define MBFL_OUTPUTFILTER_ILLEGAL_MODE_NONE
#define MBFL_VERSION_MINOR
#define MBFL_OUTPUTFILTER_ILLEGAL_MODE_ENTITY
#define MBFL_OUTPUTFILTER_ILLEGAL_MODE_CHAR
const mbfl_encoding mbfl_encoding_8bit
const mbfl_encoding mbfl_encoding_base64
const mbfl_encoding mbfl_encoding_sjis_mac
const mbfl_encoding mbfl_encoding_html_ent
const mbfl_encoding mbfl_encoding_pass
const mbfl_encoding mbfl_encoding_qprint
const mbfl_encoding mbfl_encoding_ascii
const mbfl_encoding mbfl_encoding_ucs4be
const mbfl_encoding mbfl_encoding_utf16be
const mbfl_encoding mbfl_encoding_utf16le
const mbfl_encoding mbfl_encoding_utf8
const mbfl_encoding mbfl_encoding_uuencode
#define MBFL_ENCTYPE_SBCS
#define MBFL_ENCTYPE_GL_UNSAFE
#define MBFL_ENCTYPE_WCS4
#define MBFL_ENCTYPE_WCS2
zend_string * mb_fast_convert(unsigned char *in, size_t in_len, const mbfl_encoding *from, const mbfl_encoding *to, uint32_t replacement_char, unsigned int error_mode, unsigned int *num_errors)
const mbfl_encoding ** mbfl_get_supported_encodings(void)
const mbfl_encoding * mbfl_name2encoding_ex(const char *name, size_t name_len)
const mbfl_encoding * mbfl_name2encoding(const char *name)
const mbfl_encoding * mbfl_no2encoding(enum mbfl_no_encoding no_encoding)
const char * mbfl_encoding_preferred_mime_name(const mbfl_encoding *encoding)
const char * mbfl_no_encoding2name(enum mbfl_no_encoding no_encoding)
@ mbfl_no_encoding_8859_9
@ mbfl_no_encoding_cp50220
@ mbfl_no_encoding_charset_min
@ mbfl_no_encoding_cp50222
@ mbfl_no_encoding_invalid
@ mbfl_no_encoding_euc_kr
@ mbfl_no_encoding_euc_cn
@ mbfl_no_encoding_utf7imap
@ mbfl_no_encoding_euc_tw
@ mbfl_no_encoding_2022jpms
@ mbfl_no_encoding_euc_jp
@ mbfl_no_encoding_base64
@ mbfl_no_encoding_armscii8
@ mbfl_no_encoding_cp1251
@ mbfl_no_encoding_qprint
@ mbfl_no_encoding_utf8_sb
@ mbfl_no_encoding_cp1254
#define MB_CONVERT_BUF_STORE(buf, _out, _limit)
#define MB_CONVERT_BUF_ENSURE(buf, out, limit, needed)
#define MBSTRING_MIN_WCHAR_BUFSIZE
#define MB_CONVERT_BUF_LOAD(buf, _out, _limit)
const char * mbfl_no_language2name(enum mbfl_no_language no_language)
const mbfl_language * mbfl_no2language(enum mbfl_no_language no_language)
enum mbfl_no_language mbfl_name2no_language(const char *name)
struct _mbfl_language mbfl_language
@ mbfl_no_language_korean
@ mbfl_no_language_turkish
@ mbfl_no_language_russian
@ mbfl_no_language_armenian
@ mbfl_no_language_ukrainian
@ mbfl_no_language_japanese
@ mbfl_no_language_invalid
@ mbfl_no_language_neutral
@ mbfl_no_language_traditional_chinese
@ mbfl_no_language_simplified_chinese
struct _mbfl_string mbfl_string
MBSTRING_API size_t php_mb_mbchar_bytes(const char *s, const mbfl_encoding *enc)
MBSTRING_API char * php_mb_safe_strrchr(const char *s, unsigned int c, size_t nbytes, const mbfl_encoding *enc)
#define PHP_MBSTR_MAIL_MIME_HEADER4
struct _php_mb_nls_ident_list php_mb_nls_ident_list
#define DEC_ENTITY_MINLEN
MBSTRING_API const mbfl_encoding * mb_guess_encoding_for_strings(const unsigned char **strings, size_t *str_lengths, size_t n, const mbfl_encoding **elist, unsigned int elist_size, bool strict, bool order_significant)
#define mb_fast_check_utf8
#define HEX_ENTITY_MAXLEN
char mb_convert_kana_flags[17]
MBSTRING_API size_t php_mb_stripos(bool mode, zend_string *haystack, zend_string *needle, zend_long offset, const mbfl_encoding *enc)
MBSTRING_API bool php_mb_check_encoding(const char *input, size_t length, const mbfl_encoding *encoding)
#define DEC_ENTITY_MAXLEN
MBSTRING_API zend_string * php_mb_convert_encoding_ex(const char *input, size_t length, const mbfl_encoding *to_encoding, const mbfl_encoding *from_encoding)
MBSTRING_API zend_string * php_mb_convert_encoding(const char *input, size_t length, const mbfl_encoding *to_encoding, const mbfl_encoding **from_encodings, size_t num_from_encodings)
#define HEX_ENTITY_MINLEN
#define MBSTRING_HEADER_ENC_WCHAR_BUFSIZE
#define PHP_MBSTR_MAIL_MIME_HEADER2
zend_module_entry mbstring_module_entry
MBSTRING_API HashTable * php_mb_convert_encoding_recursive(HashTable *input, const mbfl_encoding *to_encoding, const mbfl_encoding **from_encodings, size_t num_from_encodings)
uint32_t mb_convert_kana_codepoint(uint32_t c, uint32_t next, bool *consumed, uint32_t *second, int mode)
#define PHP_MBSTR_MAIL_MIME_HEADER3
#define PHP_MBSTR_MAIL_MIME_HEADER1
size_t http_input_list_size
size_t current_detect_order_list_size
zend_string * last_used_encoding_name
uint32_t filter_illegal_substchar
enum mbfl_no_language language
const mbfl_encoding ** current_detect_order_list
const mbfl_encoding ** http_input_list
const mbfl_encoding * internal_encoding
const mbfl_encoding ** detect_order_list
size_t detect_order_list_size
uint32_t current_filter_illegal_substchar
const mbfl_encoding * http_output_encoding
const mbfl_encoding * http_input_identify_string
#define PHP_MBSTRING_VERSION
int current_filter_illegal_mode
const mbfl_encoding * http_input_identify_post
HashTable * all_encodings_list
void * http_output_conv_mimetypes
char * internal_encoding_name
const mbfl_encoding * current_internal_encoding
const mbfl_encoding * http_input_identify
enum mbfl_no_encoding * default_detect_order_list
bool internal_encoding_set
const mbfl_encoding * last_used_encoding
size_t default_detect_order_list_size
const mbfl_encoding * current_http_output_encoding
bool encoding_translation
const mbfl_encoding * http_input_identify_get
const mbfl_encoding * http_input_identify_cookie
unsigned int outconv_state
mb_get_info(string $type="all")
mb_send_mail(string $to, string $subject, string $message, array|string $additional_headers=[], ?string $additional_params=null)
mb_convert_variables(string $to_encoding, array|string $from_encoding, mixed &$var, mixed &... $vars)
mb_strtoupper(string $string, ?string $encoding=null)
mb_trim(string $string, ?string $characters=null, ?string $encoding=null)
mb_strcut(string $string, int $start, ?int $length=null, ?string $encoding=null)
mb_strimwidth(string $string, int $start, int $width, string $trim_marker="", ?string $encoding=null)
mb_output_handler(string $string, int $status)
mb_encode_numericentity(string $string, array $map, ?string $encoding=null, bool $hex=false)
mb_decode_mimeheader(string $string)
mb_internal_encoding(?string $encoding=null)
mb_lcfirst(string $string, ?string $encoding=null)
mb_convert_case(string $string, int $mode, ?string $encoding=null)
mb_scrub(string $string, ?string $encoding=null)
mb_strrpos(string $haystack, string $needle, int $offset=0, ?string $encoding=null)
mb_ucfirst(string $string, ?string $encoding=null)
mb_language(?string $language=null)
mb_strstr(string $haystack, string $needle, bool $before_needle=false, ?string $encoding=null)
mb_preferred_mime_name(string $encoding)
mb_detect_encoding(string $string, array|string|null $encodings=null, bool $strict=false)
mb_decode_numericentity(string $string, array $map, ?string $encoding=null)
mb_strripos(string $haystack, string $needle, int $offset=0, ?string $encoding=null)
mb_http_input(?string $type=null)
mb_check_encoding(array|string|null $value=null, ?string $encoding=null)
mb_substr_count(string $haystack, string $needle, ?string $encoding=null)
mb_encoding_aliases(string $encoding)
mb_chr(int $codepoint, ?string $encoding=null)
mb_str_pad(string $string, int $length, string $pad_string=" ", int $pad_type=STR_PAD_RIGHT, ?string $encoding=null)
mb_http_output(?string $encoding=null)
mb_stripos(string $haystack, string $needle, int $offset=0, ?string $encoding=null)
mb_detect_order(array|string|null $encoding=null)
mb_substitute_character(string|int|null $substitute_character=null)
mb_encode_mimeheader(string $string, ?string $charset=null, ?string $transfer_encoding=null, string $newline="\r\n", int $indent=0)
mb_strwidth(string $string, ?string $encoding=null)
mb_convert_encoding(array|string $string, string $to_encoding, array|string|null $from_encoding=null)
mb_substr(string $string, int $start, ?int $length=null, ?string $encoding=null)
mb_ltrim(string $string, ?string $characters=null, ?string $encoding=null)
mb_convert_kana(string $string, string $mode="KV", ?string $encoding=null)
mb_strtolower(string $string, ?string $encoding=null)
mb_parse_str(string $string, &$result)
mb_ord(string $string, ?string $encoding=null)
mb_rtrim(string $string, ?string $characters=null, ?string $encoding=null)
mb_strpos(string $haystack, string $needle, int $offset=0, ?string $encoding=null)
mb_stristr(string $haystack, string $needle, bool $before_needle=false, ?string $encoding=null)
mb_strrchr(string $haystack, string $needle, bool $before_needle=false, ?string $encoding=null)
mb_strlen(string $string, ?string $encoding=null)
mb_strrichr(string $haystack, string $needle, bool $before_needle=false, ?string $encoding=null)
mb_str_split(string $string, int $length=1, ?string $encoding=null)
#define PCRE2_ZERO_TERMINATED
#define pcre2_get_error_message
php_info_print_table_start()
php_info_print_table_row(2, "PDO Driver for Firebird", "enabled")
php_info_print_table_end()
#define PHP_MSHUTDOWN_FUNCTION
#define PHP_MINIT_FUNCTION
#define PHP_MINFO_FUNCTION
#define PHP_GINIT_FUNCTION
#define PHP_RINIT_FUNCTION
#define PHP_RSHUTDOWN_FUNCTION
#define PHP_GSHUTDOWN_FUNCTION
#define PHP_MODULE_GLOBALS
#define DEFAULT_POST_CONTENT_TYPE
unsigned const char * end
unsigned const char * pos
#define PHP_INI_STAGE_RUNTIME
#define STD_PHP_INI_ENTRY
#define STD_PHP_INI_BOOLEAN
#define PHP_OUTPUT_HANDLER_END
#define PHP_OUTPUT_HANDLER_START
struct php_pcntl_pending_signal * head
PHPAPI pcre2_match_context * php_pcre_mctx(void)
PHPAPI pcre2_compile_context * php_pcre_cctx(void)
PHPAPI pcre2_match_data * php_pcre_create_match_data(uint32_t capture_count, pcre2_code *re)
PHPAPI void php_pcre_free_match_data(pcre2_match_data *match_data)
PHPAPI char * php_strtok_r(char *s, const char *delim, char **last)
unsigned char key[REFLECTION_KEY_LEN]
xmlCharEncodingHandlerPtr encoding
#define PHP_STR_PAD_RIGHT
PHPAPI zend_string * php_trim(zend_string *str, const char *what, size_t what_len, int mode)
MBSTRING_API zend_string * php_unicode_convert_case(php_case_mode case_mode, const char *srcstr, size_t in_len, const mbfl_encoding *src_encoding, const mbfl_encoding *dst_encoding, int illegal_mode, uint32_t illegal_substchar)
@ PHP_UNICODE_CASE_FOLD_SIMPLE
@ PHP_UNICODE_CASE_MODE_MAX
SAPI_API void php_rfc1867_set_multibyte_callbacks(php_rfc1867_encoding_translation_t encoding_translation, php_rfc1867_get_detect_order_t get_detect_order, php_rfc1867_set_input_encoding_t set_input_encoding, php_rfc1867_getword_t getword, php_rfc1867_getword_conf_t getword_conf, php_rfc1867_basename_t basename)
#define MULTIPART_CONTENT_TYPE
enum mbfl_no_encoding mail_header_encoding
enum mbfl_no_encoding mail_charset
enum mbfl_no_encoding mail_body_encoding
const mbfl_encoding ** from_encodings
size_t num_from_encodings
const mbfl_encoding * to_encoding
enum mbfl_no_language lang
enum mbfl_no_encoding * list
const mbfl_encoding * enc
const unsigned char * mblen_table
enum mbfl_no_encoding no_encoding
mb_from_wchar_fn from_wchar
#define MBFL_ZEN2HAN_HIRAGANA
#define MBFL_HAN2ZEN_ALPHA
#define MBFL_HAN2ZEN_GLUE
#define MBFL_ZENKAKU_KATA2HIRA
#define MBFL_ZEN2HAN_ALPHA
#define MBFL_HAN2ZEN_NUMERIC
#define MBFL_HAN2ZEN_KATAKANA
#define MBFL_ZEN2HAN_NUMERIC
#define MBFL_HAN2ZEN_HIRAGANA
#define MBFL_ZENKAKU_HIRA2KATA
#define MBFL_ZEN2HAN_KATAKANA
ZEND_API ZEND_COLD void zend_throw_error(zend_class_entry *exception_ce, const char *format,...)
ZEND_API ZEND_COLD void zend_value_error(const char *format,...)
#define ZEND_TSRMLS_CACHE_UPDATE()
#define INTERNAL_FUNCTION_PARAMETERS
#define ZEND_TSRMLS_CACHE_DEFINE()
#define INTERNAL_FUNCTION_PARAM_PASSTHRU
ZEND_API zend_result add_next_index_stringl(zval *arg, const char *str, size_t length)
ZEND_API ZEND_COLD void zend_argument_must_not_be_empty_error(uint32_t arg_num)
ZEND_API ZEND_COLD void zend_argument_value_error(uint32_t arg_num, const char *format,...)
ZEND_API zend_result add_next_index_string(zval *arg, const char *str)
ZEND_API zend_result add_next_index_str(zval *arg, zend_string *str)
#define Z_PARAM_PATH_STR(dest)
#define Z_PARAM_ARRAY_HT_OR_STR_OR_NULL(dest_ht, dest_str)
#define Z_PARAM_PATH_OR_NULL(dest, dest_len)
#define ZEND_PARSE_PARAMETERS_END()
#define Z_PARAM_STR_OR_NULL(dest)
#define ZEND_PARSE_PARAMETERS_NONE()
#define ZVAL_STRING(z, s)
#define ZEND_DECLARE_MODULE_GLOBALS(module_name)
#define array_init_size(arg, size)
#define ZEND_GET_MODULE(name)
#define Z_PARAM_STRING(dest, dest_len)
#define Z_PARAM_STR(dest)
#define Z_PARAM_STRING_OR_NULL(dest, dest_len)
#define Z_PARAM_STR_OR_LONG_OR_NULL(dest_str, dest_long, is_null)
#define ZEND_PARSE_PARAMETERS_START(min_num_args, max_num_args)
#define Z_PARAM_ARRAY_HT_OR_STR(dest_ht, dest_str)
#define Z_PARAM_LONG(dest)
#define Z_PARAM_VARIADIC(spec, dest, dest_num)
#define RETURN_NEW_STR(s)
#define Z_PARAM_ARRAY_HT(dest)
#define Z_PARAM_LONG_OR_NULL(dest, is_null)
#define Z_PARAM_BOOL(dest)
#define RETURN_EMPTY_ARRAY()
#define RETURN_EMPTY_STRING()
#define Z_PARAM_PATH(dest, dest_len)
#define Z_PARAM_ZVAL(dest)
#define RETVAL_STRINGL(s, l)
#define Z_PARAM_PATH_STR_OR_NULL(dest)
#define RETURN_STR_COPY(s)
#define estrndup(s, length)
#define ecalloc(nmemb, size)
#define pefree(ptr, persistent)
#define safe_emalloc(nmemb, size, offset)
#define pecalloc(nmemb, size, persistent)
strncmp(string $string1, string $string2, int $length)
zend_string_release_ex(func->internal_function.function_name, 0)
struct _zend_property_info zend_property_info
#define strncasecmp(s1, s2, n)
#define strcasecmp(s1, s2)
#define ZEND_NO_SANITIZE_ADDRESS
ZEND_API void(ZEND_FASTCALL *zend_touch_vm_stack_data)(void *vm_stack_data)
#define ZEND_REF_DEL_TYPE_SOURCE(ref, source)
ZEND_API void ZEND_FASTCALL zend_hash_destroy(HashTable *ht)
ZEND_API zval *ZEND_FASTCALL zend_hash_str_find(const HashTable *ht, const char *str, size_t len)
ZEND_API zval *ZEND_FASTCALL zend_hash_index_add(HashTable *ht, zend_ulong h, zval *pData)
ZEND_API zval *ZEND_FASTCALL zend_hash_next_index_insert(HashTable *ht, zval *pData)
ZEND_API zval *ZEND_FASTCALL zend_hash_index_add_new(HashTable *ht, zend_ulong h, zval *pData)
ZEND_API void ZEND_FASTCALL zend_array_destroy(HashTable *ht)
ZEND_API zval *ZEND_FASTCALL zend_hash_update(HashTable *ht, zend_string *key, zval *pData)
ZEND_API zval *ZEND_FASTCALL zend_hash_add(HashTable *ht, zend_string *key, zval *pData)
#define zend_hash_init(ht, nSize, pHashFunction, pDestructor, persistent)
#define zend_new_array(size)
#define ZEND_HASH_FOREACH_KEY_VAL(ht, _h, _key, _val)
#define ZEND_HASH_FOREACH_VAL_IND(ht, _val)
#define ZEND_HASH_FOREACH_END()
#define ZVAL_EMPTY_ARRAY(z)
#define ZEND_HASH_FOREACH_VAL(ht, _val)
ZEND_API zend_string * zend_ini_str_ex(const char *name, size_t name_length, bool orig, bool *exists)
ZEND_API zend_result zend_alter_ini_entry(zend_string *name, zend_string *new_value, int modify_type, int stage)
ZEND_API zend_string * zend_ini_str(const char *name, size_t name_length, bool orig)
#define UNREGISTER_INI_ENTRIES()
#define REGISTER_INI_ENTRIES()
#define DISPLAY_INI_ENTRIES()
struct _zend_string zend_string
#define INIT_FUNC_ARGS_PASSTHRU
#define ZEND_MODULE_INFO_FUNC_ARGS_PASSTHRU
struct _zend_module_dep zend_module_dep
struct _zend_module_entry zend_module_entry
#define ZEND_MOD_REQUIRED(name)
#define STANDARD_MODULE_PROPERTIES_EX
#define STANDARD_MODULE_HEADER_EX
ZEND_API void zend_multibyte_restore_functions(void)
ZEND_API zend_result zend_multibyte_set_internal_encoding(const zend_encoding *encoding)
ZEND_API zend_result zend_multibyte_set_functions(const zend_multibyte_functions *functions)
struct _zend_encoding zend_encoding
struct _zend_multibyte_functions zend_multibyte_functions
ZEND_API zend_long ZEND_FASTCALL zval_try_get_long(const zval *op, bool *failed)
ZEND_API void ZEND_FASTCALL zend_str_tolower(char *str, size_t length)
#define ZEND_INTRIN_AVX2_FUNC_DECL(func)
#define ZEND_ATTRIBUTE_UNUSED
#define ZEND_UNREACHABLE()
#define EMPTY_SWITCH_DEFAULT_CASE()
#define UNEXPECTED(condition)
ZEND_API zend_string * zend_string_concat2(const char *str1, size_t str1_len, const char *str2, size_t str2_len)
ZEND_API zend_string * zend_empty_string
#define ZSTR_IS_VALID_UTF8(s)
#define ZSTR_IS_INTERNED(s)
#define ZSTR_INIT_LITERAL(s, persistent)
#define zend_string_equals_ci(s1, s2)
#define zend_string_equals_literal_ci(str, c)
#define Z_ISREF_P(zval_p)
#define Z_REFVAL_P(zval_p)
#define Z_STRVAL_P(zval_p)
#define Z_ARRVAL_P(zval_p)
#define Z_REFCOUNTED_P(zval_p)
struct _zend_array HashTable
#define IS_STR_VALID_UTF8
#define Z_UNPROTECT_RECURSION_P(zv)
#define Z_STRLEN_P(zval_p)
#define GC_TRY_UNPROTECT_RECURSION(p)
#define GC_TRY_PROTECT_RECURSION(p)
#define GC_UNPROTECT_RECURSION(p)
#define Z_INDIRECT_P(zval_p)
#define Z_PROTECT_RECURSION_P(zv)
ZEND_RESULT_CODE zend_result
#define SEPARATE_ARRAY(zv)
#define GC_IS_RECURSIVE(p)
#define GC_ADD_FLAGS(p, flags)
#define Z_IS_RECURSIVE_P(zv)
ZEND_API void zval_ptr_dtor(zval *zval_ptr)