PluginProbe ʕ •ᴥ•ʔ
Independent Analytics – WordPress Analytics Plugin / 2.15.3
Independent Analytics – WordPress Analytics Plugin v2.15.3
2.15.4 2.15.3 2.15.2 2.15.1 2.15.0 2.14.10 trunk 1.1 1.10 1.10.1 1.11 1.12 1.13 1.14 1.15 1.16 1.17 1.17.1 1.17.2 1.17.3 1.17.4 1.18 1.18.1 1.19.0 1.19.1 1.2 1.20.0 1.21.0 1.22.0 1.22.1 1.23.0 1.23.1 1.24.0 1.24.1 1.25.0 1.25.1 1.26.0 1.27.0 1.28.0 1.28.1 1.28.2 1.28.3 1.29.0 1.3 1.30.0 1.30.1 1.4 1.5 1.6 1.7 1.8 1.9 2.0.0 2.0.1 2.1.4 2.1.5 2.1.6 2.10.0 2.10.1 2.10.2 2.10.3 2.10.4 2.11.0 2.11.1 2.11.10 2.11.2 2.11.3 2.11.4 2.11.5 2.11.6 2.11.7 2.11.8 2.11.9 2.12.0 2.12.1 2.12.2 2.13.1 2.13.2 2.13.5 2.13.6 2.14.0 2.14.1 2.14.2 2.14.4 2.14.6 2.14.7 2.14.8 2.14.9 2.2.0 2.2.1 2.3.1 2.3.2 2.4.2 2.4.3 2.5.0 2.5.1 2.6.0 2.6.1 2.6.2 2.6.3 2.6.4 2.7.0 2.7.1 2.7.2 2.7.3 2.8.2 2.8.3 2.8.4 2.8.5 2.8.6 2.8.7 2.8.8 2.8.9 2.9.2 2.9.3 2.9.4 2.9.5 2.9.6 2.9.7
independent-analytics / vendor / symfony / polyfill-mbstring / Mbstring.php
independent-analytics / vendor / symfony / polyfill-mbstring Last commit date
Resources 2 years ago Mbstring.php 3 weeks ago bootstrap.php 3 weeks ago bootstrap72.php 3 weeks ago bootstrap80.php 3 weeks ago
Mbstring.php
914 lines
1 <?php
2
3 /*
4 * This file is part of the Symfony package.
5 *
6 * (c) Fabien Potencier <fabien@symfony.com>
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11 namespace Symfony\Polyfill\Mbstring;
12
13 /**
14 * Partial mbstring implementation in PHP, iconv based, UTF-8 centric.
15 *
16 * Implemented:
17 * - mb_chr - Returns a specific character from its Unicode code point
18 * - mb_convert_encoding - Convert character encoding
19 * - mb_convert_variables - Convert character code in variable(s)
20 * - mb_decode_mimeheader - Decode string in MIME header field
21 * - mb_encode_mimeheader - Encode string for MIME header XXX NATIVE IMPLEMENTATION IS REALLY BUGGED
22 * - mb_decode_numericentity - Decode HTML numeric string reference to character
23 * - mb_encode_numericentity - Encode character to HTML numeric string reference
24 * - mb_convert_case - Perform case folding on a string
25 * - mb_detect_encoding - Detect character encoding
26 * - mb_get_info - Get internal settings of mbstring
27 * - mb_http_input - Detect HTTP input character encoding
28 * - mb_http_output - Set/Get HTTP output character encoding
29 * - mb_internal_encoding - Set/Get internal character encoding
30 * - mb_list_encodings - Returns an array of all supported encodings
31 * - mb_ord - Returns the Unicode code point of a character
32 * - mb_output_handler - Callback function converts character encoding in output buffer
33 * - mb_scrub - Replaces ill-formed byte sequences with substitute characters
34 * - mb_strlen - Get string length
35 * - mb_strpos - Find position of first occurrence of string in a string
36 * - mb_strrpos - Find position of last occurrence of a string in a string
37 * - mb_str_split - Convert a string to an array
38 * - mb_strtolower - Make a string lowercase
39 * - mb_strtoupper - Make a string uppercase
40 * - mb_substitute_character - Set/Get substitution character
41 * - mb_substr - Get part of string
42 * - mb_stripos - Finds position of first occurrence of a string within another, case insensitive
43 * - mb_stristr - Finds first occurrence of a string within another, case insensitive
44 * - mb_strrchr - Finds the last occurrence of a character in a string within another
45 * - mb_strrichr - Finds the last occurrence of a character in a string within another, case insensitive
46 * - mb_strripos - Finds position of last occurrence of a string within another, case insensitive
47 * - mb_strstr - Finds first occurrence of a string within another
48 * - mb_strwidth - Return width of string
49 * - mb_substr_count - Count the number of substring occurrences
50 * - mb_ucfirst - Make a string's first character uppercase
51 * - mb_lcfirst - Make a string's first character lowercase
52 * - mb_trim - Strip whitespace (or other characters) from the beginning and end of a string
53 * - mb_ltrim - Strip whitespace (or other characters) from the beginning of a string
54 * - mb_rtrim - Strip whitespace (or other characters) from the end of a string
55 *
56 * Not implemented:
57 * - mb_convert_kana - Convert "kana" one from another ("zen-kaku", "han-kaku" and more)
58 * - mb_ereg_* - Regular expression with multibyte support
59 * - mb_parse_str - Parse GET/POST/COOKIE data and set global variable
60 * - mb_preferred_mime_name - Get MIME charset string
61 * - mb_regex_encoding - Returns current encoding for multibyte regex as string
62 * - mb_regex_set_options - Set/Get the default options for mbregex functions
63 * - mb_send_mail - Send encoded mail
64 * - mb_split - Split multibyte string using regular expression
65 * - mb_strcut - Get part of string
66 * - mb_strimwidth - Get truncated string with specified width
67 *
68 * @author Nicolas Grekas <p@tchwork.com>
69 *
70 * @internal
71 */
72 final class Mbstring
73 {
74 public const MB_CASE_FOLD = \PHP_INT_MAX;
75 private const SIMPLE_CASE_FOLD = [['µ', 'ſ', "�
76 ", 'ς', "ϐ", "ϑ", "ϕ", "ϖ", "ϰ", "ϱ", "ϵ", "", ""], ['μ', 's', 'ι', 'σ', 'β', 'θ', 'φ', 'π', 'κ', 'ρ', 'ε', "", 'ι']];
77 private static $encodingList = ['ASCII', 'UTF-8'];
78 private static $language = 'neutral';
79 private static $internalEncoding = 'UTF-8';
80 private static $iconvSupportsIgnore;
81 public static function mb_convert_encoding($s, $toEncoding, $fromEncoding = null)
82 {
83 if (\is_array($s)) {
84 $r = [];
85 foreach ($s as $str) {
86 $r[] = self::mb_convert_encoding($str, $toEncoding, $fromEncoding);
87 }
88 return $r;
89 }
90 if (\is_array($fromEncoding) || null !== $fromEncoding && \false !== \strpos($fromEncoding, ',')) {
91 $fromEncoding = self::mb_detect_encoding($s, $fromEncoding);
92 } else {
93 $fromEncoding = self::getEncoding($fromEncoding);
94 }
95 $toEncoding = self::getEncoding($toEncoding);
96 if ('BASE64' === $fromEncoding) {
97 $s = \base64_decode($s);
98 $fromEncoding = $toEncoding;
99 }
100 if ('BASE64' === $toEncoding) {
101 return \base64_encode($s);
102 }
103 if ('HTML-ENTITIES' === $toEncoding || 'HTML' === $toEncoding) {
104 if ('HTML-ENTITIES' === $fromEncoding || 'HTML' === $fromEncoding) {
105 $fromEncoding = 'Windows-1252';
106 }
107 if ('UTF-8' !== $fromEncoding) {
108 $s = self::iconv($fromEncoding, 'UTF-8', $s);
109 }
110 return \preg_replace_callback('/[\\x80-\\xFF]+/', [__CLASS__, 'html_encoding_callback'], $s);
111 }
112 if ('HTML-ENTITIES' === $fromEncoding) {
113 $decodeControlChars = static function ($m) {
114 $code = '' !== ($m[2] ?? '') ? \hexdec($m[2]) : (int) $m[1];
115 if ($code < 32 || 127 === $code) {
116 return \chr($code);
117 }
118 if (128 <= $code && $code <= 159) {
119 return "\xc2" . \chr(0x80 | $code & 0x3f);
120 }
121 return $m[0];
122 };
123 if (\PHP_VERSION_ID >= 70400) {
124 $s = \html_entity_decode($s, \ENT_QUOTES, 'UTF-8');
125 // html_entity_decode() leaves numeric entities for C0/C1 control
126 // characters as-is (HTML spec), but mb_convert_encoding() decodes
127 // them. Catch what html_entity_decode() missed.
128 if (\false !== \strpos($s, '&#')) {
129 $s = \preg_replace_callback('/&#(?:0*([0-9]++)|[xX]0*([0-9a-fA-F]++));/', $decodeControlChars, $s);
130 }
131 } else {
132 // PHP < 7.4: html_entity_decode() truncates strings at NUL bytes,
133 // so decode the control character entities first then call
134 // html_entity_decode() on each NUL-delimited chunk independently.
135 $s = \preg_replace_callback('/&#(?:0*([0-9]++)|[xX]0*([0-9a-fA-F]++));/', $decodeControlChars, $s);
136 $s = \implode("\x00", \array_map(static function ($chunk) {
137 return \html_entity_decode($chunk, \ENT_QUOTES, 'UTF-8');
138 }, \explode("\x00", $s)));
139 }
140 $fromEncoding = 'UTF-8';
141 }
142 return self::iconv($fromEncoding, $toEncoding, $s);
143 }
144 public static function mb_convert_variables($toEncoding, $fromEncoding, &...$vars)
145 {
146 $ok = \true;
147 \array_walk_recursive($vars, static function (&$v) use(&$ok, $toEncoding, $fromEncoding) {
148 if (\false === ($v = self::mb_convert_encoding($v, $toEncoding, $fromEncoding))) {
149 $ok = \false;
150 }
151 });
152 return $ok ? $fromEncoding : \false;
153 }
154 public static function mb_decode_mimeheader($s)
155 {
156 return \iconv_mime_decode($s, 2, self::$internalEncoding);
157 }
158 public static function mb_encode_mimeheader($s, $charset = null, $transferEncoding = null, $linefeed = null, $indent = null)
159 {
160 \trigger_error('mb_encode_mimeheader() is bugged. Please use iconv_mime_encode() instead', \E_USER_WARNING);
161 }
162 public static function mb_decode_numericentity($s, $convmap, $encoding = null)
163 {
164 if (null !== $s && !\is_scalar($s) && !(\is_object($s) && \method_exists($s, '__toString'))) {
165 \trigger_error('mb_decode_numericentity() expects parameter 1 to be string, ' . \gettype($s) . ' given', \E_USER_WARNING);
166 return null;
167 }
168 if (!\is_array($convmap) || 80000 > \PHP_VERSION_ID && !$convmap) {
169 return \false;
170 }
171 if (null !== $encoding && !\is_scalar($encoding)) {
172 \trigger_error('mb_decode_numericentity() expects parameter 3 to be string, ' . \gettype($s) . ' given', \E_USER_WARNING);
173 return '';
174 // Instead of null (cf. mb_encode_numericentity).
175 }
176 $s = (string) $s;
177 if ('' === $s) {
178 return '';
179 }
180 $encoding = self::getEncoding($encoding);
181 if ('UTF-8' === $encoding) {
182 $encoding = null;
183 if (!\preg_match('//u', $s)) {
184 $s = @self::iconv('UTF-8', 'UTF-8', $s);
185 }
186 } else {
187 $s = self::iconv($encoding, 'UTF-8', $s);
188 }
189 $cnt = \floor(\count($convmap) / 4) * 4;
190 for ($i = 0; $i < $cnt; $i += 4) {
191 // collector_decode_htmlnumericentity ignores $convmap[$i + 3]
192 $convmap[$i] += $convmap[$i + 2];
193 $convmap[$i + 1] += $convmap[$i + 2];
194 }
195 $s = \preg_replace_callback('/&#(?:0*([0-9]+)|x0*([0-9a-fA-F]+))' . (\PHP_VERSION_ID >= 80200 ? '' : '(?!&)') . ';?/', static function (array $m) use($cnt, $convmap) {
196 $c = isset($m[2]) ? (int) \hexdec($m[2]) : $m[1];
197 for ($i = 0; $i < $cnt; $i += 4) {
198 if ($c >= $convmap[$i] && $c <= $convmap[$i + 1]) {
199 return self::mb_chr($c - $convmap[$i + 2]);
200 }
201 }
202 return $m[0];
203 }, $s);
204 if (null === $encoding) {
205 return $s;
206 }
207 return self::iconv('UTF-8', $encoding, $s);
208 }
209 public static function mb_encode_numericentity($s, $convmap, $encoding = null, $is_hex = \false)
210 {
211 if (null !== $s && !\is_scalar($s) && !(\is_object($s) && \method_exists($s, '__toString'))) {
212 \trigger_error('mb_encode_numericentity() expects parameter 1 to be string, ' . \gettype($s) . ' given', \E_USER_WARNING);
213 return null;
214 }
215 if (!\is_array($convmap) || 80000 > \PHP_VERSION_ID && !$convmap) {
216 return \false;
217 }
218 if (null !== $encoding && !\is_scalar($encoding)) {
219 \trigger_error('mb_encode_numericentity() expects parameter 3 to be string, ' . \gettype($s) . ' given', \E_USER_WARNING);
220 return null;
221 // Instead of '' (cf. mb_decode_numericentity).
222 }
223 if (null !== $is_hex && !\is_scalar($is_hex)) {
224 \trigger_error('mb_encode_numericentity() expects parameter 4 to be boolean, ' . \gettype($s) . ' given', \E_USER_WARNING);
225 return null;
226 }
227 $s = (string) $s;
228 if ('' === $s) {
229 return '';
230 }
231 $encoding = self::getEncoding($encoding);
232 if ('UTF-8' === $encoding) {
233 $encoding = null;
234 if (!\preg_match('//u', $s)) {
235 $s = @self::iconv('UTF-8', 'UTF-8', $s);
236 }
237 } else {
238 $s = self::iconv($encoding, 'UTF-8', $s);
239 }
240 static $ulenMask = ["\xc0" => 2, "\xd0" => 2, "\xe0" => 3, "\xf0" => 4];
241 $cnt = \floor(\count($convmap) / 4) * 4;
242 $i = 0;
243 $len = \strlen($s);
244 $result = '';
245 while ($i < $len) {
246 $ulen = $s[$i] < "\x80" ? 1 : $ulenMask[$s[$i] & "\xf0"];
247 $uchr = \substr($s, $i, $ulen);
248 $i += $ulen;
249 $c = self::mb_ord($uchr);
250 for ($j = 0; $j < $cnt; $j += 4) {
251 if ($c >= $convmap[$j] && $c <= $convmap[$j + 1]) {
252 $cOffset = $c + $convmap[$j + 2] & $convmap[$j + 3];
253 $result .= $is_hex ? \sprintf('&#x%X;', $cOffset) : '&#' . $cOffset . ';';
254 continue 2;
255 }
256 }
257 $result .= $uchr;
258 }
259 if (null === $encoding) {
260 return $result;
261 }
262 return self::iconv('UTF-8', $encoding, $result);
263 }
264 public static function mb_convert_case($s, $mode, $encoding = null)
265 {
266 $s = (string) $s;
267 if ('' === $s) {
268 return '';
269 }
270 $encoding = self::getEncoding($encoding);
271 if ('UTF-8' === $encoding) {
272 $encoding = null;
273 if (!\preg_match('//u', $s)) {
274 $s = @self::iconv('UTF-8', 'UTF-8', $s);
275 }
276 } else {
277 $s = self::iconv($encoding, 'UTF-8', $s);
278 }
279 if (\MB_CASE_TITLE == $mode) {
280 static $titleRegexp = null;
281 if (null === $titleRegexp) {
282 $titleRegexp = self::getData('titleCaseRegexp');
283 }
284 $s = \preg_replace_callback($titleRegexp, [__CLASS__, 'title_case'], $s);
285 } else {
286 if (\MB_CASE_UPPER == $mode) {
287 static $upper = null;
288 if (null === $upper) {
289 $upper = self::getData('upperCase');
290 }
291 $map = $upper;
292 } else {
293 if (self::MB_CASE_FOLD === $mode) {
294 static $caseFolding = null;
295 if (null === $caseFolding) {
296 $caseFolding = self::getData('caseFolding');
297 }
298 $s = \strtr($s, $caseFolding);
299 }
300 static $lower = null;
301 if (null === $lower) {
302 $lower = self::getData('lowerCase');
303 }
304 $map = $lower;
305 }
306 static $ulenMask = ["\xc0" => 2, "\xd0" => 2, "\xe0" => 3, "\xf0" => 4];
307 $i = 0;
308 $len = \strlen($s);
309 while ($i < $len) {
310 $ulen = $s[$i] < "\x80" ? 1 : $ulenMask[$s[$i] & "\xf0"];
311 $uchr = \substr($s, $i, $ulen);
312 $i += $ulen;
313 if (isset($map[$uchr])) {
314 $uchr = $map[$uchr];
315 $nlen = \strlen($uchr);
316 if ($nlen == $ulen) {
317 $nlen = $i;
318 do {
319 $s[--$nlen] = $uchr[--$ulen];
320 } while ($ulen);
321 } else {
322 $s = \substr_replace($s, $uchr, $i - $ulen, $ulen);
323 $len += $nlen - $ulen;
324 $i += $nlen - $ulen;
325 }
326 }
327 }
328 }
329 if (null === $encoding) {
330 return $s;
331 }
332 return self::iconv('UTF-8', $encoding, $s);
333 }
334 public static function mb_internal_encoding($encoding = null)
335 {
336 if (null === $encoding) {
337 return self::$internalEncoding;
338 }
339 $normalizedEncoding = self::getEncoding($encoding);
340 if ('UTF-8' === $normalizedEncoding || \false !== @\iconv($normalizedEncoding, $normalizedEncoding, ' ')) {
341 self::$internalEncoding = $normalizedEncoding;
342 return \true;
343 }
344 if (80000 > \PHP_VERSION_ID) {
345 return \false;
346 }
347 throw new \ValueError(\sprintf('Argument #1 ($encoding) must be a valid encoding, "%s" given', $encoding));
348 }
349 public static function mb_language($lang = null)
350 {
351 if (null === $lang) {
352 return self::$language;
353 }
354 switch ($normalizedLang = \strtolower($lang)) {
355 case 'uni':
356 case 'neutral':
357 self::$language = $normalizedLang;
358 return \true;
359 }
360 if (80000 > \PHP_VERSION_ID) {
361 return \false;
362 }
363 throw new \ValueError(\sprintf('Argument #1 ($language) must be a valid language, "%s" given', $lang));
364 }
365 public static function mb_list_encodings()
366 {
367 return ['UTF-8'];
368 }
369 public static function mb_encoding_aliases($encoding)
370 {
371 switch (\strtoupper($encoding)) {
372 case 'UTF8':
373 case 'UTF-8':
374 return ['utf8'];
375 }
376 return \false;
377 }
378 public static function mb_check_encoding($var = null, $encoding = null)
379 {
380 if (null === $encoding) {
381 if (null === $var) {
382 return \false;
383 }
384 $encoding = self::$internalEncoding;
385 }
386 if (!\is_array($var)) {
387 return self::mb_detect_encoding($var, [$encoding]) || \false !== @\iconv($encoding, $encoding, $var);
388 }
389 foreach ($var as $key => $value) {
390 if (!self::mb_check_encoding($key, $encoding)) {
391 return \false;
392 }
393 if (!self::mb_check_encoding($value, $encoding)) {
394 return \false;
395 }
396 }
397 return \true;
398 }
399 public static function mb_detect_encoding($str, $encodingList = null, $strict = \false)
400 {
401 if (null === $encodingList) {
402 $encodingList = self::$encodingList;
403 } else {
404 if (!\is_array($encodingList)) {
405 $encodingList = \array_map('trim', \explode(',', $encodingList));
406 }
407 $encodingList = \array_map('strtoupper', $encodingList);
408 }
409 foreach ($encodingList as $enc) {
410 switch ($enc) {
411 case 'ASCII':
412 if (!\preg_match('/[\\x80-\\xFF]/', $str)) {
413 return $enc;
414 }
415 break;
416 case 'UTF8':
417 case 'UTF-8':
418 if (\preg_match('//u', $str)) {
419 return 'UTF-8';
420 }
421 break;
422 default:
423 if (0 === \strncmp($enc, 'ISO-8859-', 9)) {
424 return $enc;
425 }
426 }
427 }
428 return \false;
429 }
430 public static function mb_detect_order($encodingList = null)
431 {
432 if (null === $encodingList) {
433 return self::$encodingList;
434 }
435 if (!\is_array($encodingList)) {
436 $encodingList = \array_map('trim', \explode(',', $encodingList));
437 }
438 $encodingList = \array_map('strtoupper', $encodingList);
439 foreach ($encodingList as $enc) {
440 switch ($enc) {
441 default:
442 if (\strncmp($enc, 'ISO-8859-', 9)) {
443 return \false;
444 }
445 // no break
446 case 'ASCII':
447 case 'UTF8':
448 case 'UTF-8':
449 }
450 }
451 self::$encodingList = $encodingList;
452 return \true;
453 }
454 public static function mb_strlen($s, $encoding = null)
455 {
456 $encoding = self::getEncoding($encoding);
457 if ('CP850' === $encoding || 'ASCII' === $encoding) {
458 return \strlen($s);
459 }
460 if (\false !== ($len = @\iconv_strlen($s, $encoding))) {
461 return $len;
462 }
463 if ('UTF-8' !== $encoding) {
464 return $len;
465 }
466 return \preg_match_all('/[\\x00-\\x7F]|[\\xC0-\\xDF][\\x80-\\xBF]?|[\\xE0-\\xEF][\\x80-\\xBF]{0,2}|[\\xF0-\\xF7][\\x80-\\xBF]{0,3}|[\\xF8-\\xFB][\\x80-\\xBF]{0,4}|[\\xFC-\\xFD][\\x80-\\xBF]{0,5}|[\\x80-\\xBF\\xFE\\xFF]/s', $s);
467 }
468 public static function mb_strpos($haystack, $needle, $offset = 0, $encoding = null)
469 {
470 $encoding = self::getEncoding($encoding);
471 if ('CP850' === $encoding || 'ASCII' === $encoding) {
472 return \strpos($haystack, $needle, $offset);
473 }
474 $needle = (string) $needle;
475 if ('' === $needle) {
476 if (80000 > \PHP_VERSION_ID) {
477 \trigger_error(__METHOD__ . ': Empty delimiter', \E_USER_WARNING);
478 return \false;
479 }
480 return 0;
481 }
482 return \iconv_strpos($haystack, $needle, $offset, $encoding);
483 }
484 public static function mb_strrpos($haystack, $needle, $offset = 0, $encoding = null)
485 {
486 $encoding = self::getEncoding($encoding);
487 if ('CP850' === $encoding || 'ASCII' === $encoding) {
488 return \strrpos($haystack, $needle, $offset);
489 }
490 if ($offset != (int) $offset) {
491 $offset = 0;
492 } elseif ($offset = (int) $offset) {
493 if ($offset < 0) {
494 if (0 > ($offset += self::mb_strlen($needle))) {
495 $haystack = self::mb_substr($haystack, 0, $offset, $encoding);
496 }
497 $offset = 0;
498 } else {
499 $haystack = self::mb_substr($haystack, $offset, 2147483647, $encoding);
500 }
501 }
502 $pos = '' !== $needle || 80000 > \PHP_VERSION_ID ? \iconv_strrpos($haystack, $needle, $encoding) : self::mb_strlen($haystack, $encoding);
503 return \false !== $pos ? $offset + $pos : \false;
504 }
505 public static function mb_str_split($string, $split_length = 1, $encoding = null)
506 {
507 if (null !== $string && !\is_scalar($string) && !(\is_object($string) && \method_exists($string, '__toString'))) {
508 \trigger_error('mb_str_split() expects parameter 1 to be string, ' . \gettype($string) . ' given', \E_USER_WARNING);
509 return null;
510 }
511 if (1 > ($split_length = (int) $split_length)) {
512 if (80000 > \PHP_VERSION_ID) {
513 \trigger_error('The length of each segment must be greater than zero', \E_USER_WARNING);
514 return \false;
515 }
516 throw new \ValueError('Argument #2 ($length) must be greater than 0');
517 }
518 if (null === $encoding) {
519 $encoding = \mb_internal_encoding();
520 }
521 if ('UTF-8' === ($encoding = self::getEncoding($encoding))) {
522 $rx = '/(';
523 while (65535 < $split_length) {
524 $rx .= '.{65535}';
525 $split_length -= 65535;
526 }
527 $rx .= '.{' . $split_length . '})/us';
528 return \preg_split($rx, $string, -1, \PREG_SPLIT_DELIM_CAPTURE | \PREG_SPLIT_NO_EMPTY);
529 }
530 $result = [];
531 $length = \mb_strlen($string, $encoding);
532 for ($i = 0; $i < $length; $i += $split_length) {
533 $result[] = \mb_substr($string, $i, $split_length, $encoding);
534 }
535 return $result;
536 }
537 public static function mb_strtolower($s, $encoding = null)
538 {
539 return self::mb_convert_case($s, \MB_CASE_LOWER, $encoding);
540 }
541 public static function mb_strtoupper($s, $encoding = null)
542 {
543 return self::mb_convert_case($s, \MB_CASE_UPPER, $encoding);
544 }
545 public static function mb_substitute_character($c = null)
546 {
547 if (null === $c) {
548 return 'none';
549 }
550 if (0 === \strcasecmp($c, 'none')) {
551 return \true;
552 }
553 if (80000 > \PHP_VERSION_ID) {
554 return \false;
555 }
556 if (\is_int($c) || 'long' === $c || 'entity' === $c) {
557 return \false;
558 }
559 throw new \ValueError('Argument #1 ($substitute_character) must be "none", "long", "entity" or a valid codepoint');
560 }
561 public static function mb_substr($s, $start, $length = null, $encoding = null)
562 {
563 $encoding = self::getEncoding($encoding);
564 if ('CP850' === $encoding || 'ASCII' === $encoding) {
565 return (string) \substr($s, $start, null === $length ? 2147483647 : $length);
566 }
567 if ($start < 0) {
568 $start = \iconv_strlen($s, $encoding) + $start;
569 if ($start < 0) {
570 $start = 0;
571 }
572 }
573 if (null === $length) {
574 $length = 2147483647;
575 } elseif ($length < 0) {
576 $length = \iconv_strlen($s, $encoding) + $length - $start;
577 if ($length < 0) {
578 return '';
579 }
580 }
581 return (string) \iconv_substr($s, $start, $length, $encoding);
582 }
583 public static function mb_stripos($haystack, $needle, $offset = 0, $encoding = null)
584 {
585 [$haystack, $needle] = \str_replace(self::SIMPLE_CASE_FOLD[0], self::SIMPLE_CASE_FOLD[1], [self::mb_convert_case($haystack, \MB_CASE_LOWER, $encoding), self::mb_convert_case($needle, \MB_CASE_LOWER, $encoding)]);
586 return self::mb_strpos($haystack, $needle, $offset, $encoding);
587 }
588 public static function mb_stristr($haystack, $needle, $part = \false, $encoding = null)
589 {
590 $pos = self::mb_stripos($haystack, $needle, 0, $encoding);
591 return self::getSubpart($pos, $part, $haystack, $encoding);
592 }
593 public static function mb_strrchr($haystack, $needle, $part = \false, $encoding = null)
594 {
595 $encoding = self::getEncoding($encoding);
596 if ('CP850' === $encoding || 'ASCII' === $encoding) {
597 $pos = \strrpos($haystack, $needle);
598 } else {
599 $needle = self::mb_substr($needle, 0, 1, $encoding);
600 $pos = \iconv_strrpos($haystack, $needle, $encoding);
601 }
602 return self::getSubpart($pos, $part, $haystack, $encoding);
603 }
604 public static function mb_strrichr($haystack, $needle, $part = \false, $encoding = null)
605 {
606 $needle = self::mb_substr($needle, 0, 1, $encoding);
607 $pos = self::mb_strripos($haystack, $needle, $encoding);
608 return self::getSubpart($pos, $part, $haystack, $encoding);
609 }
610 public static function mb_strripos($haystack, $needle, $offset = 0, $encoding = null)
611 {
612 $haystack = self::mb_convert_case($haystack, \MB_CASE_LOWER, $encoding);
613 $needle = self::mb_convert_case($needle, \MB_CASE_LOWER, $encoding);
614 $haystack = \str_replace(self::SIMPLE_CASE_FOLD[0], self::SIMPLE_CASE_FOLD[1], $haystack);
615 $needle = \str_replace(self::SIMPLE_CASE_FOLD[0], self::SIMPLE_CASE_FOLD[1], $needle);
616 return self::mb_strrpos($haystack, $needle, $offset, $encoding);
617 }
618 public static function mb_strstr($haystack, $needle, $part = \false, $encoding = null)
619 {
620 $pos = \strpos($haystack, $needle);
621 if (\false === $pos) {
622 return \false;
623 }
624 if ($part) {
625 return \substr($haystack, 0, $pos);
626 }
627 return \substr($haystack, $pos);
628 }
629 public static function mb_get_info($type = 'all')
630 {
631 $info = ['internal_encoding' => self::$internalEncoding, 'http_output' => 'pass', 'http_output_conv_mimetypes' => '^(text/|application/xhtml\\+xml)', 'func_overload' => 0, 'func_overload_list' => 'no overload', 'mail_charset' => 'UTF-8', 'mail_header_encoding' => 'BASE64', 'mail_body_encoding' => 'BASE64', 'illegal_chars' => 0, 'encoding_translation' => 'Off', 'language' => self::$language, 'detect_order' => self::$encodingList, 'substitute_character' => 'none', 'strict_detection' => 'Off'];
632 if ('all' === $type) {
633 return $info;
634 }
635 if (isset($info[$type])) {
636 return $info[$type];
637 }
638 return \false;
639 }
640 public static function mb_http_input($type = '')
641 {
642 return \false;
643 }
644 public static function mb_http_output($encoding = null)
645 {
646 return null !== $encoding ? 'pass' === $encoding : 'pass';
647 }
648 public static function mb_strwidth($s, $encoding = null)
649 {
650 $encoding = self::getEncoding($encoding);
651 if ('UTF-8' !== $encoding) {
652 $s = self::iconv($encoding, 'UTF-8', $s);
653 }
654 $s = \preg_replace('/[\\x{1100}-\\x{115F}\\x{2329}\\x{232A}\\x{2E80}-\\x{303E}\\x{3040}-\\x{A4CF}\\x{AC00}-\\x{D7A3}\\x{F900}-\\x{FAFF}\\x{FE10}-\\x{FE19}\\x{FE30}-\\x{FE6F}\\x{FF00}-\\x{FF60}\\x{FFE0}-\\x{FFE6}\\x{20000}-\\x{2FFFD}\\x{30000}-\\x{3FFFD}]/u', '', $s, -1, $wide);
655 return ($wide << 1) + \iconv_strlen($s, 'UTF-8');
656 }
657 public static function mb_substr_count($haystack, $needle, $encoding = null)
658 {
659 return \substr_count($haystack, $needle);
660 }
661 public static function mb_output_handler($contents, $status)
662 {
663 return $contents;
664 }
665 public static function mb_chr($code, $encoding = null)
666 {
667 if (0x80 > ($code %= 0x200000)) {
668 $s = \chr($code);
669 } elseif (0x800 > $code) {
670 $s = \chr(0xc0 | $code >> 6) . \chr(0x80 | $code & 0x3f);
671 } elseif (0x10000 > $code) {
672 $s = \chr(0xe0 | $code >> 12) . \chr(0x80 | $code >> 6 & 0x3f) . \chr(0x80 | $code & 0x3f);
673 } else {
674 $s = \chr(0xf0 | $code >> 18) . \chr(0x80 | $code >> 12 & 0x3f) . \chr(0x80 | $code >> 6 & 0x3f) . \chr(0x80 | $code & 0x3f);
675 }
676 if ('UTF-8' !== ($encoding = self::getEncoding($encoding))) {
677 $s = \mb_convert_encoding($s, $encoding, 'UTF-8');
678 }
679 return $s;
680 }
681 public static function mb_ord($s, $encoding = null)
682 {
683 if ('UTF-8' !== ($encoding = self::getEncoding($encoding))) {
684 $s = \mb_convert_encoding($s, 'UTF-8', $encoding);
685 }
686 if (1 === \strlen($s)) {
687 return \ord($s);
688 }
689 $code = ($s = \unpack('C*', \substr($s, 0, 4))) ? $s[1] : 0;
690 if (0xf0 <= $code) {
691 return ($code - 0xf0 << 18) + ($s[2] - 0x80 << 12) + ($s[3] - 0x80 << 6) + $s[4] - 0x80;
692 }
693 if (0xe0 <= $code) {
694 return ($code - 0xe0 << 12) + ($s[2] - 0x80 << 6) + $s[3] - 0x80;
695 }
696 if (0xc0 <= $code) {
697 return ($code - 0xc0 << 6) + $s[2] - 0x80;
698 }
699 return $code;
700 }
701 /** @return string|false */
702 public static function mb_scrub(?string $string, ?string $encoding = null) : string
703 {
704 if (null === $encoding) {
705 $encoding = self::mb_internal_encoding();
706 } elseif (!self::assertEncoding($encoding, 'mb_scrub(): Argument #2 ($encoding) must be a valid encoding, "%s" given')) {
707 return \false;
708 }
709 return self::mb_convert_encoding((string) $string, $encoding, $encoding);
710 }
711 /** @return string|false */
712 public static function mb_str_pad(string $string, int $length, string $pad_string = ' ', int $pad_type = \STR_PAD_RIGHT, ?string $encoding = null)
713 {
714 if (null === $encoding) {
715 $encoding = self::mb_internal_encoding();
716 } elseif (!self::assertEncoding($encoding, 'mb_str_pad(): Argument #5 ($encoding) must be a valid encoding, "%s" given')) {
717 return \false;
718 }
719 if (self::mb_strlen($pad_string, $encoding) <= 0) {
720 if (\PHP_VERSION_ID < 80000) {
721 \trigger_error('mb_str_pad(): Argument #3 ($pad_string) must be a non-empty string', \E_USER_WARNING);
722 return \false;
723 }
724 throw new \ValueError('mb_str_pad(): Argument #3 ($pad_string) must be a non-empty string');
725 }
726 if (!\in_array($pad_type, [\STR_PAD_RIGHT, \STR_PAD_LEFT, \STR_PAD_BOTH], \true)) {
727 if (\PHP_VERSION_ID < 80000) {
728 \trigger_error('mb_str_pad(): Argument #4 ($pad_type) must be STR_PAD_LEFT, STR_PAD_RIGHT, or STR_PAD_BOTH', \E_USER_WARNING);
729 return \false;
730 }
731 throw new \ValueError('mb_str_pad(): Argument #4 ($pad_type) must be STR_PAD_LEFT, STR_PAD_RIGHT, or STR_PAD_BOTH');
732 }
733 $paddingRequired = $length - self::mb_strlen($string, $encoding);
734 if ($paddingRequired < 1) {
735 return $string;
736 }
737 switch ($pad_type) {
738 case \STR_PAD_LEFT:
739 return self::mb_substr(\str_repeat($pad_string, $paddingRequired), 0, $paddingRequired, $encoding) . $string;
740 case \STR_PAD_RIGHT:
741 return $string . self::mb_substr(\str_repeat($pad_string, $paddingRequired), 0, $paddingRequired, $encoding);
742 default:
743 $leftPaddingLength = \floor($paddingRequired / 2);
744 $rightPaddingLength = $paddingRequired - $leftPaddingLength;
745 return self::mb_substr(\str_repeat($pad_string, $leftPaddingLength), 0, $leftPaddingLength, $encoding) . $string . self::mb_substr(\str_repeat($pad_string, $rightPaddingLength), 0, $rightPaddingLength, $encoding);
746 }
747 }
748 /** @return string|false */
749 public static function mb_ucfirst(string $string, ?string $encoding = null)
750 {
751 if (null === $encoding) {
752 $encoding = self::mb_internal_encoding();
753 } elseif (!self::assertEncoding($encoding, 'mb_ucfirst(): Argument #2 ($encoding) must be a valid encoding, "%s" given')) {
754 return \false;
755 }
756 $firstChar = \mb_substr($string, 0, 1, $encoding);
757 $firstChar = \mb_convert_case($firstChar, \MB_CASE_TITLE, $encoding);
758 return $firstChar . \mb_substr($string, 1, null, $encoding);
759 }
760 /** @return string|false */
761 public static function mb_lcfirst(string $string, ?string $encoding = null)
762 {
763 if (null === $encoding) {
764 $encoding = self::mb_internal_encoding();
765 } elseif (!self::assertEncoding($encoding, 'mb_lcfirst(): Argument #2 ($encoding) must be a valid encoding, "%s" given')) {
766 return \false;
767 }
768 $firstChar = \mb_substr($string, 0, 1, $encoding);
769 $firstChar = \mb_convert_case($firstChar, \MB_CASE_LOWER, $encoding);
770 return $firstChar . \mb_substr($string, 1, null, $encoding);
771 }
772 /** @return string|false */
773 public static function mb_trim(string $string, ?string $characters = null, ?string $encoding = null)
774 {
775 return self::mb_internal_trim('{^[%s]+|[%1$s]+$}Du', $string, $characters, $encoding, __FUNCTION__);
776 }
777 /** @return string|false */
778 public static function mb_ltrim(string $string, ?string $characters = null, ?string $encoding = null)
779 {
780 return self::mb_internal_trim('{^[%s]+}Du', $string, $characters, $encoding, __FUNCTION__);
781 }
782 /** @return string|false */
783 public static function mb_rtrim(string $string, ?string $characters = null, ?string $encoding = null)
784 {
785 return self::mb_internal_trim('{[%s]+$}Du', $string, $characters, $encoding, __FUNCTION__);
786 }
787 private static function getSubpart($pos, $part, $haystack, $encoding)
788 {
789 if (\false === $pos) {
790 return \false;
791 }
792 if ($part) {
793 return self::mb_substr($haystack, 0, $pos, $encoding);
794 }
795 return self::mb_substr($haystack, $pos, null, $encoding);
796 }
797 private static function html_encoding_callback(array $m)
798 {
799 $i = 1;
800 $entities = '';
801 $m = \unpack('C*', \htmlentities($m[0], \ENT_COMPAT, 'UTF-8'));
802 while (isset($m[$i])) {
803 if (0x80 > $m[$i]) {
804 $entities .= \chr($m[$i++]);
805 continue;
806 }
807 if (0xf0 <= $m[$i]) {
808 $c = ($m[$i++] - 0xf0 << 18) + ($m[$i++] - 0x80 << 12) + ($m[$i++] - 0x80 << 6) + $m[$i++] - 0x80;
809 } elseif (0xe0 <= $m[$i]) {
810 $c = ($m[$i++] - 0xe0 << 12) + ($m[$i++] - 0x80 << 6) + $m[$i++] - 0x80;
811 } else {
812 $c = ($m[$i++] - 0xc0 << 6) + $m[$i++] - 0x80;
813 }
814 $entities .= '&#' . $c . ';';
815 }
816 return $entities;
817 }
818 private static function title_case(array $s)
819 {
820 return self::mb_convert_case($s[1], \MB_CASE_UPPER, 'UTF-8') . self::mb_convert_case($s[2], \MB_CASE_LOWER, 'UTF-8');
821 }
822 private static function getData($file)
823 {
824 if (\file_exists($file = __DIR__ . '/Resources/unidata/' . $file . '.php')) {
825 return require $file;
826 }
827 return \false;
828 }
829 private static function getEncoding($encoding)
830 {
831 if (null === $encoding) {
832 return self::$internalEncoding;
833 }
834 if ('UTF-8' === $encoding) {
835 return 'UTF-8';
836 }
837 $encoding = \strtoupper($encoding);
838 if ('8BIT' === $encoding || 'BINARY' === $encoding) {
839 return 'CP850';
840 }
841 if ('UTF8' === $encoding) {
842 return 'UTF-8';
843 }
844 if ('UTF-32' === $encoding) {
845 return 'UTF-32BE';
846 }
847 if ('UTF-16' === $encoding) {
848 return 'UTF-16BE';
849 }
850 return $encoding;
851 }
852 private static function iconv($fromEncoding, $toEncoding, $s)
853 {
854 if (null === self::$iconvSupportsIgnore) {
855 self::$iconvSupportsIgnore = \false !== @\iconv('UTF-8', 'UTF-8//IGNORE', '');
856 }
857 return self::$iconvSupportsIgnore ? \iconv($fromEncoding, $toEncoding . '//IGNORE', $s) : \iconv($fromEncoding, $toEncoding, $s);
858 }
859 /** @return string|false */
860 private static function mb_internal_trim(string $regex, string $string, ?string $characters, ?string $encoding, string $function)
861 {
862 if (null === $encoding) {
863 $encoding = self::mb_internal_encoding();
864 } elseif (!self::assertEncoding($encoding, $function . '(): Argument #3 ($encoding) must be a valid encoding, "%s" given')) {
865 return \false;
866 }
867 if ('' === $characters) {
868 return null === $encoding ? $string : self::mb_convert_encoding($string, $encoding);
869 }
870 if ('UTF-8' === $encoding) {
871 $encoding = null;
872 if (!\preg_match('//u', $string)) {
873 $string = @self::iconv('UTF-8', 'UTF-8', $string);
874 }
875 if (null !== $characters && !\preg_match('//u', $characters)) {
876 $characters = @self::iconv('UTF-8', 'UTF-8', $characters);
877 }
878 } else {
879 $string = self::iconv($encoding, 'UTF-8', $string);
880 if (null !== $characters) {
881 $characters = self::iconv($encoding, 'UTF-8', $characters);
882 }
883 }
884 if (null === $characters) {
885 $characters = "\\0 \f\n\r\t\v       �
886      

   �
887 ";
888 } else {
889 $characters = \preg_quote($characters);
890 }
891 $string = \preg_replace(\sprintf($regex, $characters), '', $string);
892 if (null === $encoding) {
893 return $string;
894 }
895 return self::iconv('UTF-8', $encoding, $string);
896 }
897 private static function assertEncoding(string $encoding, string $errorFormat) : bool
898 {
899 try {
900 $validEncoding = @self::mb_check_encoding('', $encoding);
901 } catch (\ValueError $e) {
902 throw new \ValueError(\sprintf($errorFormat, $encoding));
903 }
904 if (!$validEncoding) {
905 if (80000 > \PHP_VERSION_ID) {
906 \trigger_error(\sprintf($errorFormat, $encoding), \E_USER_WARNING);
907 } else {
908 throw new \ValueError(\sprintf($errorFormat, $encoding));
909 }
910 }
911 return $validEncoding;
912 }
913 }
914