PluginProbe
Elementor Website Builder – more than just a page builder / 4.3.2
Elementor Website Builder – more than just a page builder v4.3.2
4.3.2 4.3.1 4.3.0 4.3.0-beta3 4.3.0-beta2 4.3.0-beta1 4.2.4 4.2.3 4.2.2 4.2.1 4.2.0 4.1.5 4.2.0-beta2 4.2.0-dev2 4.2.0-beta1 4.1.4 4.1.3 4.1.2 4.1.1 4.1.0 4.1.0-beta3 4.1.0-dev3 4.0.9 4.1.0-beta2 4.1.0-dev2 All 455 releases
elementor / vendor_prefixed / twig / symfony / polyfill-mbstring / Mbstring.php

Mbstring.php in Elementor Website Builder – more than just a page builder 4.3.2, at vendor_prefixed/twig/symfony/polyfill-mbstring/Mbstring.php

914 lines 38.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /*
4 * This file is part of the Symfony package.
5 *
6 * (c) Fabien Potencier <[email protected]>
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 ElementorDeps\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 <[email protected]>
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