PluginProbe ʕ •ᴥ•ʔ
MailPoet – Newsletters, Email Marketing, and Automation / 5.12.13
MailPoet – Newsletters, Email Marketing, and Automation v5.12.13
5.32.0 5.31.0 5.30.0 5.29.0 5.28.1 5.28.0 5.27.0 5.26.0 5.26.1 5.25.0 5.24.0 4.43.0 4.43.1 4.44.0 4.44.1 4.45.0 4.46.0 4.47.0 4.48.0 4.48.1 4.48.2 4.49.0 4.49.1 4.5.0 4.5.1 4.5.2 4.50.0 4.50.1 4.51.0 4.51.1 4.51.2 4.52.0 4.53.0 4.54.0 4.55.0 4.56.0 4.57.0 4.58.0 4.58.1 4.58.2 4.6.0 4.6.1 4.6.2 4.7.0 4.7.1 4.8.0 4.8.1 4.9.0 5.0.0 5.0.1 5.0.2 5.1.0 5.1.1 5.10.0 5.10.1 5.11.0 5.12.0 5.12.1 5.12.10 5.12.11 5.12.12 5.12.13 5.12.2 5.12.3 5.12.4 5.12.5 5.12.6 5.12.7 5.12.8 5.12.9 5.13.0 5.13.1 5.13.2 5.14.0 5.14.1 5.14.2 5.14.3 5.15.0 5.15.1 5.16.0 5.16.1 5.16.2 5.16.3 5.16.4 5.17.0 5.17.1 5.17.2 5.17.3 5.17.4 5.17.5 5.17.6 5.18.0 5.19.0 5.2.0 5.2.1 5.2.2 5.2.3 5.20.0 5.21.0 5.21.1 5.21.2 5.21.3 5.22.0 5.22.1 5.22.2 5.22.3 5.22.4 5.23.0 5.23.1 5.23.2 5.3.0 5.3.1 5.3.2 5.3.3 5.3.4 5.3.5 5.3.6 5.3.7 5.4.0 5.4.1 5.4.2 5.5.0 5.5.1 5.5.2 5.6.0 5.6.1 5.6.2 5.6.3 5.6.4 5.7.0 5.7.1 5.8.0 5.8.1 5.9.0 3.0.0-beta.15 3.7.1 3.0.0-beta.16 3.7.2 3.0.0-beta.17 3.7.3 3.0.0-beta.18 3.7.4 3.0.0-beta.19 3.7.5 3.0.0-beta.2 3.7.6 3.0.0-beta.20 3.7.8 3.0.0-beta.21 3.70.0 3.0.0-beta.22 3.71.0 3.0.0-beta.23 3.71.1 3.0.0-beta.23.1 3.71.2 3.0.0-beta.23.2 3.71.3 3.0.0-beta.24 3.72.0 3.0.0-beta.25 3.73.0 3.0.0-beta.26 3.73.1 3.0.0-beta.27 3.73.2 3.0.0-beta.28 3.74.0 3.0.0-beta.29 3.74.1 3.0.0-beta.3 3.74.2 3.0.0-beta.30 3.74.3 3.0.0-beta.31 3.75.0 3.0.0-beta.32 3.75.1 3.0.0-beta.33 3.76.0 3.0.0-beta.33.1 3.77.0 3.0.0-beta.34.0.0 3.77.1 3.0.0-beta.36.0.0 3.78.0 3.0.0-beta.36.0.1 3.79.0 3.0.0-beta.36.2.0 3.8 3.0.0-beta.36.3.0 3.8.1 3.0.0-beta.36.3.1 3.8.2 3.0.0-beta.37.0.0 3.8.3 3.0.0-beta.4 3.8.4 3.0.0-beta.5 3.8.5 3.0.0-beta.6 3.8.6 3.0.0-beta.7 3.80.0 3.0.0-beta.7.1 3.81.0 3.0.0-beta.8 3.82.0 3.0.0-beta.9 3.83.0 3.0.0-rc.1.0.0 3.84.0 3.0.0-rc.1.0.1 3.84.1 3.0.0-rc.1.0.2 3.85.0 3.0.0-rc.1.0.3 3.85.1 3.0.0-rc.1.0.4 3.86.0 3.0.0-rc.2.0.0 3.87.0 3.0.0-rc.2.0.1 3.87.1 3.0.0-rc.2.0.2 3.87.2 3.0.0-rc.2.0.3 3.88.0 3.0.1 3.88.1 3.0.2 3.88.2 3.0.3 3.89.0 3.0.4 3.89.1 3.0.5 3.89.2 3.0.6 3.89.3 3.0.7 3.89.4 3.0.8 3.9.0 3.0.9 3.9.1 3.1.0 3.90.0 3.10 3.90.1 3.10.1 3.90.2 3.100.0 3.91.0 3.100.1 3.91.1 3.100.2 3.92.0 3.101.0 3.92.1 3.101.1 3.93.0 3.102.0 3.93.1 3.102.1 3.94.0 3.103.0 3.95.0 3.103.1 3.95.1 3.11.0 3.96.0 3.11.1 3.96.1 3.11.2 3.97.0 3.11.3 3.98.0 3.11.4 3.98.1 3.11.5 3.99.0 3.12.0 3.99.1 3.12.1 4.0.0 3.13.0 4.0.1 3.14.0 4.1.0 3.14.1 4.1.1 3.15.0 4.10.0 3.16.0 4.11.0 3.16.1 4.11.1 3.16.2 4.12.0 3.16.3 4.12.1 3.17.0 4.12.2 3.17.1 4.13.0 3.17.2 4.14.0 3.18.0 4.15.0 3.18.1 4.16.0 3.18.2 4.17.0 3.19.0 4.17.1 3.19.1 4.18.0 3.19.2 4.18.1 3.19.3 4.19.0 3.2.0 4.2.0 3.2.1 4.20.0 3.2.2 4.20.1 3.2.3 4.20.2 3.2.4 4.21.0 3.2.5 4.22.0 3.20.0 4.22.1 3.21.0 4.22.2 3.21.1 4.23.0 3.22.0 4.24.0 3.23.0 4.25.0 3.23.1 4.26.0 3.23.2 4.26.1 3.24.0 4.27.0 3.25.0 4.28.0 3.25.1 4.29.0 3.26.0 4.3.0 3.26.1 4.3.1 3.27.0 4.30.0 3.28.0 4.31.0 3.29.0 4.31.1 3.3.0 4.32.0 3.3.1 4.33.0 3.3.2 4.34.0 3.3.3 4.35.0 3.3.4 4.35.1 3.3.5 4.36.0 3.3.6 4.37.0 3.30.0 4.38.0 3.31.0 4.39.0 3.31.1 4.4.0 3.32.0 4.40.0 3.32.1 4.41.0 3.32.2 4.41.1 3.33.0 4.41.2 3.34.0 4.41.3 3.34.1 4.42.0 3.34.2 4.42.1 3.34.3 3.34.4 3.35.0 3.35.1 3.35.3 3.35.4 3.36.0 3.37.0 3.37.1 3.37.2 3.37.3 3.38.0 3.38.1 3.39.0 3.39.1 3.39.2 3.4.0 3.4.1 3.4.2 3.4.3 3.4.4 3.40.0 3.40.1 3.41.0 3.41.1 3.41.2 3.42.0 3.42.1 3.42.2 3.42.3 3.43.0 3.43.1 3.44.0 3.45.0 3.45.1 3.46.0 3.46.1 3.46.10 3.46.11 3.46.12 3.46.13 3.46.14 3.46.2 3.46.3 3.46.4 3.46.5 3.46.6 3.46.7 3.46.8 3.46.9 3.47.0 3.47.1 3.47.10 3.47.11 3.47.2 3.47.3 3.47.5 3.47.6 3.47.7 3.47.9 3.48.0 3.48.1 3.49.0 3.49.1 3.5.0 3.5.1 3.50.0 3.51.0 3.51.1 3.51.2 3.52.0 3.53.0 3.54.0 3.54.1 3.54.2 3.54.3 3.55.0 3.55.1 3.56.0 3.56.1 3.56.2 3.57.0 3.57.1 3.58.0 3.59.0 3.59.1 3.59.2 3.6.0 3.6.1 3.6.2 3.6.3 3.6.4 3.6.5 3.6.6 3.6.7 3.60.0 3.60.1 3.60.10 3.60.11 3.60.12 3.60.2 3.60.3 3.60.4 3.60.6 3.60.7 3.60.8 3.60.9 3.61.0 3.62.0 3.62.1 3.63.0 3.64.0 3.64.1 3.64.2 3.64.3 3.65.0 trunk 3.65.1 3.0.0 3.66.0 3.0.0-beta.1 3.67.0 3.0.0-beta.10 3.67.1 3.0.0-beta.11 3.68.0 3.0.0-beta.12 3.69.0 3.0.0-beta.13 3.69.1 3.0.0-beta.14 3.7.0
mailpoet / vendor-prefixed / symfony / polyfill-iconv / Iconv.php
mailpoet / vendor-prefixed / symfony / polyfill-iconv Last commit date
Resources 1 year ago Iconv.php 1 year ago bootstrap.php 1 year ago bootstrap80.php 1 year ago index.php 3 years ago
Iconv.php
507 lines
1 <?php
2 namespace MailPoetVendor\Symfony\Polyfill\Iconv;
3 if (!defined('ABSPATH')) exit;
4 final class Iconv
5 {
6 public const ERROR_ILLEGAL_CHARACTER = 'iconv(): Detected an illegal character in input string';
7 public const ERROR_WRONG_CHARSET = 'iconv(): Wrong charset, conversion from `%s\' to `%s\' is not allowed';
8 public static $inputEncoding = 'utf-8';
9 public static $outputEncoding = 'utf-8';
10 public static $internalEncoding = 'utf-8';
11 private static $alias = ['utf8' => 'utf-8', 'ascii' => 'us-ascii', 'tis-620' => 'iso-8859-11', 'cp1250' => 'windows-1250', 'cp1251' => 'windows-1251', 'cp1252' => 'windows-1252', 'cp1253' => 'windows-1253', 'cp1254' => 'windows-1254', 'cp1255' => 'windows-1255', 'cp1256' => 'windows-1256', 'cp1257' => 'windows-1257', 'cp1258' => 'windows-1258', 'shift-jis' => 'cp932', 'shift_jis' => 'cp932', 'latin1' => 'iso-8859-1', 'latin2' => 'iso-8859-2', 'latin3' => 'iso-8859-3', 'latin4' => 'iso-8859-4', 'latin5' => 'iso-8859-9', 'latin6' => 'iso-8859-10', 'latin7' => 'iso-8859-13', 'latin8' => 'iso-8859-14', 'latin9' => 'iso-8859-15', 'latin10' => 'iso-8859-16', 'iso8859-1' => 'iso-8859-1', 'iso8859-2' => 'iso-8859-2', 'iso8859-3' => 'iso-8859-3', 'iso8859-4' => 'iso-8859-4', 'iso8859-5' => 'iso-8859-5', 'iso8859-6' => 'iso-8859-6', 'iso8859-7' => 'iso-8859-7', 'iso8859-8' => 'iso-8859-8', 'iso8859-9' => 'iso-8859-9', 'iso8859-10' => 'iso-8859-10', 'iso8859-11' => 'iso-8859-11', 'iso8859-12' => 'iso-8859-12', 'iso8859-13' => 'iso-8859-13', 'iso8859-14' => 'iso-8859-14', 'iso8859-15' => 'iso-8859-15', 'iso8859-16' => 'iso-8859-16', 'iso_8859-1' => 'iso-8859-1', 'iso_8859-2' => 'iso-8859-2', 'iso_8859-3' => 'iso-8859-3', 'iso_8859-4' => 'iso-8859-4', 'iso_8859-5' => 'iso-8859-5', 'iso_8859-6' => 'iso-8859-6', 'iso_8859-7' => 'iso-8859-7', 'iso_8859-8' => 'iso-8859-8', 'iso_8859-9' => 'iso-8859-9', 'iso_8859-10' => 'iso-8859-10', 'iso_8859-11' => 'iso-8859-11', 'iso_8859-12' => 'iso-8859-12', 'iso_8859-13' => 'iso-8859-13', 'iso_8859-14' => 'iso-8859-14', 'iso_8859-15' => 'iso-8859-15', 'iso_8859-16' => 'iso-8859-16', 'iso88591' => 'iso-8859-1', 'iso88592' => 'iso-8859-2', 'iso88593' => 'iso-8859-3', 'iso88594' => 'iso-8859-4', 'iso88595' => 'iso-8859-5', 'iso88596' => 'iso-8859-6', 'iso88597' => 'iso-8859-7', 'iso88598' => 'iso-8859-8', 'iso88599' => 'iso-8859-9', 'iso885910' => 'iso-8859-10', 'iso885911' => 'iso-8859-11', 'iso885912' => 'iso-8859-12', 'iso885913' => 'iso-8859-13', 'iso885914' => 'iso-8859-14', 'iso885915' => 'iso-8859-15', 'iso885916' => 'iso-8859-16'];
12 private static $translitMap = [];
13 private static $convertMap = [];
14 private static $errorHandler;
15 private static $lastError;
16 private static $ulenMask = ["\xc0" => 2, "\xd0" => 2, "\xe0" => 3, "\xf0" => 4];
17 private static $isValidUtf8;
18 public static function iconv($inCharset, $outCharset, $str)
19 {
20 $str = (string) $str;
21 if ('' === $str) {
22 return '';
23 }
24 // Prepare for //IGNORE and //TRANSLIT
25 $translit = $ignore = '';
26 $outCharset = \strtolower($outCharset);
27 $inCharset = \strtolower($inCharset);
28 if ('' === $outCharset) {
29 $outCharset = 'iso-8859-1';
30 }
31 if ('' === $inCharset) {
32 $inCharset = 'iso-8859-1';
33 }
34 do {
35 $loop = \false;
36 if ('//translit' === \substr($outCharset, -10)) {
37 $loop = $translit = \true;
38 $outCharset = \substr($outCharset, 0, -10);
39 }
40 if ('//ignore' === \substr($outCharset, -8)) {
41 $loop = $ignore = \true;
42 $outCharset = \substr($outCharset, 0, -8);
43 }
44 } while ($loop);
45 do {
46 $loop = \false;
47 if ('//translit' === \substr($inCharset, -10)) {
48 $loop = \true;
49 $inCharset = \substr($inCharset, 0, -10);
50 }
51 if ('//ignore' === \substr($inCharset, -8)) {
52 $loop = \true;
53 $inCharset = \substr($inCharset, 0, -8);
54 }
55 } while ($loop);
56 if (isset(self::$alias[$inCharset])) {
57 $inCharset = self::$alias[$inCharset];
58 }
59 if (isset(self::$alias[$outCharset])) {
60 $outCharset = self::$alias[$outCharset];
61 }
62 // Load charset maps
63 if ('utf-8' !== $inCharset && !self::loadMap('from.', $inCharset, $inMap) || 'utf-8' !== $outCharset && !self::loadMap('to.', $outCharset, $outMap)) {
64 \trigger_error(\sprintf(self::ERROR_WRONG_CHARSET, $inCharset, $outCharset));
65 return \false;
66 }
67 if ('utf-8' !== $inCharset) {
68 // Convert input to UTF-8
69 $result = '';
70 if (self::mapToUtf8($result, $inMap, $str, $ignore)) {
71 $str = $result;
72 } else {
73 $str = \false;
74 }
75 self::$isValidUtf8 = \true;
76 } else {
77 self::$isValidUtf8 = \preg_match('//u', $str);
78 if (!self::$isValidUtf8 && !$ignore) {
79 \trigger_error(self::ERROR_ILLEGAL_CHARACTER);
80 return \false;
81 }
82 if ('utf-8' === $outCharset) {
83 // UTF-8 validation
84 $str = self::utf8ToUtf8($str, $ignore);
85 }
86 }
87 if ('utf-8' !== $outCharset && \false !== $str) {
88 // Convert output to UTF-8
89 $result = '';
90 if (self::mapFromUtf8($result, $outMap, $str, $ignore, $translit)) {
91 return $result;
92 }
93 return \false;
94 }
95 return $str;
96 }
97 public static function iconv_mime_decode_headers($str, $mode = 0, $charset = null)
98 {
99 if (null === $charset) {
100 $charset = self::$internalEncoding;
101 }
102 if (\false !== \strpos($str, "\r")) {
103 $str = \strtr(\str_replace("\r\n", "\n", $str), "\r", "\n");
104 }
105 $str = \explode("\n\n", $str, 2);
106 $headers = [];
107 $str = \preg_split('/\\n(?![ \\t])/', $str[0]);
108 foreach ($str as $str) {
109 $str = self::iconv_mime_decode($str, $mode, $charset);
110 if (\false === $str) {
111 return \false;
112 }
113 $str = \explode(':', $str, 2);
114 if (2 === \count($str)) {
115 if (isset($headers[$str[0]])) {
116 if (!\is_array($headers[$str[0]])) {
117 $headers[$str[0]] = [$headers[$str[0]]];
118 }
119 $headers[$str[0]][] = \ltrim($str[1]);
120 } else {
121 $headers[$str[0]] = \ltrim($str[1]);
122 }
123 }
124 }
125 return $headers;
126 }
127 public static function iconv_mime_decode($str, $mode = 0, $charset = null)
128 {
129 if (null === $charset) {
130 $charset = self::$internalEncoding;
131 }
132 if (\ICONV_MIME_DECODE_CONTINUE_ON_ERROR & $mode) {
133 $charset .= '//IGNORE';
134 }
135 if (\false !== \strpos($str, "\r")) {
136 $str = \strtr(\str_replace("\r\n", "\n", $str), "\r", "\n");
137 }
138 $str = \preg_split('/\\n(?![ \\t])/', \rtrim($str), 2);
139 $str = \preg_replace('/[ \\t]*\\n[ \\t]+/', ' ', \rtrim($str[0]));
140 $str = \preg_split('/=\\?([^?]+)\\?([bqBQ])\\?(.*?)\\?=/', $str, -1, \PREG_SPLIT_DELIM_CAPTURE);
141 $result = self::iconv('utf-8', $charset, $str[0]);
142 if (\false === $result) {
143 return \false;
144 }
145 $i = 1;
146 $len = \count($str);
147 while ($i < $len) {
148 $c = \strtolower($str[$i]);
149 if (\ICONV_MIME_DECODE_CONTINUE_ON_ERROR & $mode && 'utf-8' !== $c && !isset(self::$alias[$c]) && !self::loadMap('from.', $c, $d)) {
150 $d = \false;
151 } elseif ('B' === \strtoupper($str[$i + 1])) {
152 $d = \base64_decode($str[$i + 2]);
153 } else {
154 $d = \rawurldecode(\strtr(\str_replace('%', '%25', $str[$i + 2]), '=_', '% '));
155 }
156 if (\false !== $d) {
157 if ('' !== $d) {
158 if ('' === ($d = self::iconv($c, $charset, $d))) {
159 $str[$i + 3] = \substr($str[$i + 3], 1);
160 } else {
161 $result .= $d;
162 }
163 }
164 $d = self::iconv('utf-8', $charset, $str[$i + 3]);
165 if ('' !== \trim($d)) {
166 $result .= $d;
167 }
168 } elseif (\ICONV_MIME_DECODE_CONTINUE_ON_ERROR & $mode) {
169 $result .= "=?{$str[$i]}?{$str[$i + 1]}?{$str[$i + 2]}?={$str[$i + 3]}";
170 } else {
171 $result = \false;
172 break;
173 }
174 $i += 4;
175 }
176 return $result;
177 }
178 public static function iconv_get_encoding($type = 'all')
179 {
180 switch ($type) {
181 case 'input_encoding':
182 return self::$inputEncoding;
183 case 'output_encoding':
184 return self::$outputEncoding;
185 case 'internal_encoding':
186 return self::$internalEncoding;
187 }
188 return ['input_encoding' => self::$inputEncoding, 'output_encoding' => self::$outputEncoding, 'internal_encoding' => self::$internalEncoding];
189 }
190 public static function iconv_set_encoding($type, $charset)
191 {
192 switch ($type) {
193 case 'input_encoding':
194 self::$inputEncoding = $charset;
195 break;
196 case 'output_encoding':
197 self::$outputEncoding = $charset;
198 break;
199 case 'internal_encoding':
200 self::$internalEncoding = $charset;
201 break;
202 default:
203 return \false;
204 }
205 return \true;
206 }
207 public static function iconv_mime_encode($fieldName, $fieldValue, $pref = null)
208 {
209 if (!\is_array($pref)) {
210 $pref = [];
211 }
212 $pref += ['scheme' => 'B', 'input-charset' => self::$internalEncoding, 'output-charset' => self::$internalEncoding, 'line-length' => 76, 'line-break-chars' => "\r\n"];
213 if (\preg_match('/[\\x80-\\xFF]/', $fieldName)) {
214 $fieldName = '';
215 }
216 $scheme = \strtoupper(\substr($pref['scheme'], 0, 1));
217 $in = \strtolower($pref['input-charset']);
218 $out = \strtolower($pref['output-charset']);
219 if ('utf-8' !== $in && \false === ($fieldValue = self::iconv($in, 'utf-8', $fieldValue))) {
220 return \false;
221 }
222 \preg_match_all('/./us', $fieldValue, $chars);
223 $chars = $chars[0] ?? [];
224 $lineBreak = (int) $pref['line-length'];
225 $lineStart = "=?{$pref['output-charset']}?{$scheme}?";
226 $lineLength = \strlen($fieldName) + 2 + \strlen($lineStart) + 2;
227 $lineOffset = \strlen($lineStart) + 3;
228 $lineData = '';
229 $fieldValue = [];
230 $Q = 'Q' === $scheme;
231 foreach ($chars as $c) {
232 if ('utf-8' !== $out && \false === ($c = self::iconv('utf-8', $out, $c))) {
233 return \false;
234 }
235 $o = $Q ? $c = \preg_replace_callback('/[=_\\?\\x00-\\x1F\\x80-\\xFF]/', [__CLASS__, 'qpByteCallback'], $c) : \base64_encode($lineData . $c);
236 if (isset($o[$lineBreak - $lineLength])) {
237 if (!$Q) {
238 $lineData = \base64_encode($lineData);
239 }
240 $fieldValue[] = $lineStart . $lineData . '?=';
241 $lineLength = $lineOffset;
242 $lineData = '';
243 }
244 $lineData .= $c;
245 $Q && ($lineLength += \strlen($c));
246 }
247 if ('' !== $lineData) {
248 if (!$Q) {
249 $lineData = \base64_encode($lineData);
250 }
251 $fieldValue[] = $lineStart . $lineData . '?=';
252 }
253 return $fieldName . ': ' . \implode($pref['line-break-chars'] . ' ', $fieldValue);
254 }
255 public static function iconv_strlen($s, $encoding = null)
256 {
257 static $hasXml = null;
258 if (null === $hasXml) {
259 $hasXml = \extension_loaded('xml');
260 }
261 if ($hasXml) {
262 return self::strlen1($s, $encoding);
263 }
264 return self::strlen2($s, $encoding);
265 }
266 public static function strlen1($s, $encoding = null)
267 {
268 if (null === $encoding) {
269 $encoding = self::$internalEncoding;
270 }
271 if (0 !== \stripos($encoding, 'utf-8') && \false === ($s = self::iconv($encoding, 'utf-8', $s))) {
272 return \false;
273 }
274 return \strlen(\utf8_decode($s));
275 }
276 public static function strlen2($s, $encoding = null)
277 {
278 if (null === $encoding) {
279 $encoding = self::$internalEncoding;
280 }
281 if (0 !== \stripos($encoding, 'utf-8') && \false === ($s = self::iconv($encoding, 'utf-8', $s))) {
282 return \false;
283 }
284 $ulenMask = self::$ulenMask;
285 $i = 0;
286 $j = 0;
287 $len = \strlen($s);
288 while ($i < $len) {
289 $u = $s[$i] & "\xf0";
290 $i += $ulenMask[$u] ?? 1;
291 ++$j;
292 }
293 return $j;
294 }
295 public static function iconv_strpos($haystack, $needle, $offset = 0, $encoding = null)
296 {
297 if (null === $encoding) {
298 $encoding = self::$internalEncoding;
299 }
300 if (0 !== \stripos($encoding, 'utf-8')) {
301 if (\false === ($haystack = self::iconv($encoding, 'utf-8', $haystack))) {
302 return \false;
303 }
304 if (\false === ($needle = self::iconv($encoding, 'utf-8', $needle))) {
305 return \false;
306 }
307 }
308 if ($offset = (int) $offset) {
309 $haystack = self::iconv_substr($haystack, $offset, 2147483647, 'utf-8');
310 }
311 $pos = \strpos($haystack, $needle);
312 return \false === $pos ? \false : $offset + ($pos ? self::iconv_strlen(\substr($haystack, 0, $pos), 'utf-8') : 0);
313 }
314 public static function iconv_strrpos($haystack, $needle, $encoding = null)
315 {
316 if (null === $encoding) {
317 $encoding = self::$internalEncoding;
318 }
319 if (0 !== \stripos($encoding, 'utf-8')) {
320 if (\false === ($haystack = self::iconv($encoding, 'utf-8', $haystack))) {
321 return \false;
322 }
323 if (\false === ($needle = self::iconv($encoding, 'utf-8', $needle))) {
324 return \false;
325 }
326 }
327 $pos = isset($needle[0]) ? \strrpos($haystack, $needle) : \false;
328 return \false === $pos ? \false : self::iconv_strlen($pos ? \substr($haystack, 0, $pos) : $haystack, 'utf-8');
329 }
330 public static function iconv_substr($s, $start, $length = 2147483647, $encoding = null)
331 {
332 if (null === $encoding) {
333 $encoding = self::$internalEncoding;
334 }
335 if (0 !== \stripos($encoding, 'utf-8')) {
336 $encoding = null;
337 } elseif (\false === ($s = self::iconv($encoding, 'utf-8', $s))) {
338 return \false;
339 }
340 $s = (string) $s;
341 $slen = self::iconv_strlen($s, 'utf-8');
342 $start = (int) $start;
343 if (0 > $start) {
344 $start += $slen;
345 }
346 if (0 > $start) {
347 if (\PHP_VERSION_ID < 80000) {
348 return \false;
349 }
350 $start = 0;
351 }
352 if ($start >= $slen) {
353 return \PHP_VERSION_ID >= 80000 ? '' : \false;
354 }
355 $rx = $slen - $start;
356 if (0 > $length) {
357 $length += $rx;
358 }
359 if (0 === $length) {
360 return '';
361 }
362 if (0 > $length) {
363 return \PHP_VERSION_ID >= 80000 ? '' : \false;
364 }
365 if ($length > $rx) {
366 $length = $rx;
367 }
368 $rx = '/^' . ($start ? self::pregOffset($start) : '') . '(' . self::pregOffset($length) . ')/u';
369 $s = \preg_match($rx, $s, $s) ? $s[1] : '';
370 if (null === $encoding) {
371 return $s;
372 }
373 return self::iconv('utf-8', $encoding, $s);
374 }
375 private static function loadMap($type, $charset, &$map)
376 {
377 if (!isset(self::$convertMap[$type . $charset])) {
378 if (\false === ($map = self::getData($type . $charset))) {
379 if ('to.' === $type && self::loadMap('from.', $charset, $map)) {
380 $map = \array_flip($map);
381 } else {
382 return \false;
383 }
384 }
385 self::$convertMap[$type . $charset] = $map;
386 } else {
387 $map = self::$convertMap[$type . $charset];
388 }
389 return \true;
390 }
391 private static function utf8ToUtf8($str, $ignore)
392 {
393 $ulenMask = self::$ulenMask;
394 $valid = self::$isValidUtf8;
395 $u = $str;
396 $i = $j = 0;
397 $len = \strlen($str);
398 while ($i < $len) {
399 if ($str[$i] < "\x80") {
400 $u[$j++] = $str[$i++];
401 } else {
402 $ulen = $str[$i] & "\xf0";
403 $ulen = $ulenMask[$ulen] ?? 1;
404 $uchr = \substr($str, $i, $ulen);
405 if (1 === $ulen || !($valid || \preg_match('/^.$/us', $uchr))) {
406 if ($ignore) {
407 ++$i;
408 continue;
409 }
410 \trigger_error(self::ERROR_ILLEGAL_CHARACTER);
411 return \false;
412 }
413 $i += $ulen;
414 $u[$j++] = $uchr[0];
415 isset($uchr[1]) && 0 !== ($u[$j++] = $uchr[1]) && isset($uchr[2]) && 0 !== ($u[$j++] = $uchr[2]) && isset($uchr[3]) && 0 !== ($u[$j++] = $uchr[3]);
416 }
417 }
418 return \substr($u, 0, $j);
419 }
420 private static function mapToUtf8(&$result, array $map, $str, $ignore)
421 {
422 $len = \strlen($str);
423 for ($i = 0; $i < $len; ++$i) {
424 if (isset($str[$i + 1], $map[$str[$i] . $str[$i + 1]])) {
425 $result .= $map[$str[$i] . $str[++$i]];
426 } elseif (isset($map[$str[$i]])) {
427 $result .= $map[$str[$i]];
428 } elseif (!$ignore) {
429 \trigger_error(self::ERROR_ILLEGAL_CHARACTER);
430 return \false;
431 }
432 }
433 return \true;
434 }
435 private static function mapFromUtf8(&$result, array $map, $str, $ignore, $translit)
436 {
437 $ulenMask = self::$ulenMask;
438 $valid = self::$isValidUtf8;
439 if ($translit && !self::$translitMap) {
440 self::$translitMap = self::getData('translit');
441 }
442 $i = 0;
443 $len = \strlen($str);
444 while ($i < $len) {
445 if ($str[$i] < "\x80") {
446 $uchr = $str[$i++];
447 } else {
448 $ulen = $str[$i] & "\xf0";
449 $ulen = $ulenMask[$ulen] ?? 1;
450 $uchr = \substr($str, $i, $ulen);
451 if ($ignore && (1 === $ulen || !($valid || \preg_match('/^.$/us', $uchr)))) {
452 ++$i;
453 continue;
454 }
455 $i += $ulen;
456 }
457 if (isset($map[$uchr])) {
458 $result .= $map[$uchr];
459 } elseif ($translit) {
460 if (isset(self::$translitMap[$uchr])) {
461 $uchr = self::$translitMap[$uchr];
462 } elseif ($uchr >= "À") {
463 $uchr = \MailPoetVendor\Normalizer::normalize($uchr, \MailPoetVendor\Normalizer::NFD);
464 if ($uchr[0] < "\x80") {
465 $uchr = $uchr[0];
466 } elseif ($ignore) {
467 continue;
468 } else {
469 return \false;
470 }
471 } elseif ($ignore) {
472 continue;
473 } else {
474 return \false;
475 }
476 $str = $uchr . \substr($str, $i);
477 $len = \strlen($str);
478 $i = 0;
479 } elseif (!$ignore) {
480 return \false;
481 }
482 }
483 return \true;
484 }
485 private static function qpByteCallback(array $m)
486 {
487 return '=' . \strtoupper(\dechex(\ord($m[0])));
488 }
489 private static function pregOffset($offset)
490 {
491 $rx = [];
492 $offset = (int) $offset;
493 while ($offset > 65535) {
494 $rx[] = '.{65535}';
495 $offset -= 65535;
496 }
497 return \implode('', $rx) . '.{' . $offset . '}';
498 }
499 private static function getData($file)
500 {
501 if (\file_exists($file = __DIR__ . '/Resources/charset/' . $file . '.php')) {
502 return require $file;
503 }
504 return \false;
505 }
506 }
507