1 | <?php |
||||||
2 | |||||||
3 | /** |
||||||
4 | * This file provides compatibility functions and code for older versions of |
||||||
5 | * PHP, such as the sha1() function, missing extensions, or 64-bit vs 32-bit |
||||||
6 | * systems. It is only included for those older versions or when the respective |
||||||
7 | * extension or function cannot be found. |
||||||
8 | * |
||||||
9 | * Simple Machines Forum (SMF) |
||||||
10 | * |
||||||
11 | * @package SMF |
||||||
12 | * @author Simple Machines https://www.simplemachines.org |
||||||
13 | * @copyright 2022 Simple Machines and individual contributors |
||||||
14 | * @license https://www.simplemachines.org/about/smf/license.php BSD |
||||||
15 | * |
||||||
16 | * @version 2.1.3 |
||||||
17 | */ |
||||||
18 | |||||||
19 | if (!defined('SMF')) |
||||||
20 | die('No direct access...'); |
||||||
21 | |||||||
22 | /** |
||||||
23 | * Define the old SMF sha1 function. Uses mhash if available |
||||||
24 | * |
||||||
25 | * @param string $str The string |
||||||
26 | * @return string The sha1 hashed version of $str |
||||||
27 | */ |
||||||
28 | function sha1_smf($str) |
||||||
29 | { |
||||||
30 | // If we have mhash loaded in, use it instead! |
||||||
31 | if (function_exists('mhash') && defined('MHASH_SHA1')) |
||||||
32 | return bin2hex(mhash(MHASH_SHA1, $str)); |
||||||
33 | |||||||
34 | $nblk = (strlen($str) + 8 >> 6) + 1; |
||||||
35 | $blks = array_pad(array(), $nblk * 16, 0); |
||||||
36 | |||||||
37 | for ($i = 0; $i < strlen($str); $i++) |
||||||
38 | $blks[$i >> 2] |= ord($str[$i]) << (24 - ($i % 4) * 8); |
||||||
39 | |||||||
40 | $blks[$i >> 2] |= 0x80 << (24 - ($i % 4) * 8); |
||||||
41 | |||||||
42 | return sha1_core($blks, strlen($str) * 8); |
||||||
0 ignored issues
–
show
Bug
introduced
by
![]() |
|||||||
43 | } |
||||||
44 | |||||||
45 | /** |
||||||
46 | * This is the core SHA-1 calculation routine, used by sha1(). |
||||||
47 | * |
||||||
48 | * @param string $x |
||||||
49 | * @param int $len |
||||||
50 | * @return string |
||||||
51 | */ |
||||||
52 | function sha1_core($x, $len) |
||||||
53 | { |
||||||
54 | @$x[$len >> 5] |= 0x80 << (24 - $len % 32); |
||||||
55 | $x[(($len + 64 >> 9) << 4) + 15] = $len; |
||||||
56 | |||||||
57 | $w = array(); |
||||||
58 | $a = 1732584193; |
||||||
59 | $b = -271733879; |
||||||
60 | $c = -1732584194; |
||||||
61 | $d = 271733878; |
||||||
62 | $e = -1009589776; |
||||||
63 | |||||||
64 | for ($i = 0, $n = count($x); $i < $n; $i += 16) |
||||||
0 ignored issues
–
show
$x of type string is incompatible with the type Countable|array expected by parameter $value of count() .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
65 | { |
||||||
66 | $olda = $a; |
||||||
67 | $oldb = $b; |
||||||
68 | $oldc = $c; |
||||||
69 | $oldd = $d; |
||||||
70 | $olde = $e; |
||||||
71 | |||||||
72 | for ($j = 0; $j < 80; $j++) |
||||||
73 | { |
||||||
74 | if ($j < 16) |
||||||
75 | $w[$j] = isset($x[$i + $j]) ? $x[$i + $j] : 0; |
||||||
76 | else |
||||||
77 | $w[$j] = sha1_rol($w[$j - 3] ^ $w[$j - 8] ^ $w[$j - 14] ^ $w[$j - 16], 1); |
||||||
78 | |||||||
79 | $t = sha1_rol($a, 5) + sha1_ft($j, $b, $c, $d) + $e + $w[$j] + sha1_kt($j); |
||||||
80 | $e = $d; |
||||||
81 | $d = $c; |
||||||
82 | $c = sha1_rol($b, 30); |
||||||
83 | $b = $a; |
||||||
84 | $a = $t; |
||||||
85 | } |
||||||
86 | |||||||
87 | $a += $olda; |
||||||
88 | $b += $oldb; |
||||||
89 | $c += $oldc; |
||||||
90 | $d += $oldd; |
||||||
91 | $e += $olde; |
||||||
92 | } |
||||||
93 | |||||||
94 | return sprintf('%08x%08x%08x%08x%08x', $a, $b, $c, $d, $e); |
||||||
95 | } |
||||||
96 | |||||||
97 | /** |
||||||
98 | * Helper function for the core SHA-1 calculation |
||||||
99 | * |
||||||
100 | * @param int $t |
||||||
101 | * @param int $b |
||||||
102 | * @param int $c |
||||||
103 | * @param int $d |
||||||
104 | * @return int |
||||||
105 | */ |
||||||
106 | function sha1_ft($t, $b, $c, $d) |
||||||
107 | { |
||||||
108 | if ($t < 20) |
||||||
109 | return ($b & $c) | ((~$b) & $d); |
||||||
110 | if ($t < 40) |
||||||
111 | return $b ^ $c ^ $d; |
||||||
112 | if ($t < 60) |
||||||
113 | return ($b & $c) | ($b & $d) | ($c & $d); |
||||||
114 | |||||||
115 | return $b ^ $c ^ $d; |
||||||
116 | } |
||||||
117 | |||||||
118 | /** |
||||||
119 | * Helper function for the core SHA-1 calculation |
||||||
120 | * |
||||||
121 | * @param int $t |
||||||
122 | * @return int 1518500249, 1859775393, -1894007588 or -899497514 depending on the value of $t |
||||||
123 | */ |
||||||
124 | function sha1_kt($t) |
||||||
125 | { |
||||||
126 | return $t < 20 ? 1518500249 : ($t < 40 ? 1859775393 : ($t < 60 ? -1894007588 : -899497514)); |
||||||
127 | } |
||||||
128 | |||||||
129 | /** |
||||||
130 | * Helper function for the core SHA-1 calculation |
||||||
131 | * |
||||||
132 | * @param int $num |
||||||
133 | * @param int $cnt |
||||||
134 | * @return int |
||||||
135 | */ |
||||||
136 | function sha1_rol($num, $cnt) |
||||||
137 | { |
||||||
138 | // Unfortunately, PHP uses unsigned 32-bit longs only. So we have to kludge it a bit. |
||||||
139 | if ($num & 0x80000000) |
||||||
140 | $a = ($num >> 1 & 0x7fffffff) >> (31 - $cnt); |
||||||
141 | else |
||||||
142 | $a = $num >> (32 - $cnt); |
||||||
143 | |||||||
144 | return ($num << $cnt) | $a; |
||||||
145 | } |
||||||
146 | |||||||
147 | /** |
||||||
148 | * Available since: (PHP 5) |
||||||
149 | * If the optional raw_output is set to TRUE, then the sha1 digest is instead returned in raw binary format with a length of 20, |
||||||
150 | * otherwise the returned value is a 40-character hexadecimal number. |
||||||
151 | * |
||||||
152 | * @param string $text The text to hash |
||||||
153 | * @return string The sha1 hash of $text |
||||||
154 | */ |
||||||
155 | function sha1_raw($text) |
||||||
156 | { |
||||||
157 | return sha1($text, true); |
||||||
158 | } |
||||||
159 | |||||||
160 | if (!function_exists('smf_crc32')) |
||||||
161 | { |
||||||
162 | /** |
||||||
163 | * Compatibility function. |
||||||
164 | * crc32 doesn't work as expected on 64-bit functions - make our own. |
||||||
165 | * https://php.net/crc32#79567 |
||||||
166 | * |
||||||
167 | * @param string $number |
||||||
168 | * @return string The crc32 polynomial of $number |
||||||
169 | */ |
||||||
170 | function smf_crc32($number) |
||||||
171 | { |
||||||
172 | $crc = crc32($number); |
||||||
173 | |||||||
174 | if ($crc & 0x80000000) |
||||||
175 | { |
||||||
176 | $crc ^= 0xffffffff; |
||||||
177 | $crc += 1; |
||||||
178 | $crc = -$crc; |
||||||
179 | } |
||||||
180 | |||||||
181 | return $crc; |
||||||
182 | } |
||||||
183 | } |
||||||
184 | |||||||
185 | if (!function_exists('mb_ord')) |
||||||
186 | { |
||||||
187 | /** |
||||||
188 | * Compatibility function. |
||||||
189 | * |
||||||
190 | * This is a complete polyfill. |
||||||
191 | * |
||||||
192 | * @param string $string A character. |
||||||
193 | * @param string|null $encoding The character encoding. |
||||||
194 | * If null, the current SMF encoding will be used, falling back to UTF-8. |
||||||
195 | * @return int|bool The Unicode code point of the character, or false on failure. |
||||||
196 | */ |
||||||
197 | function mb_ord($string, $encoding = null) |
||||||
198 | { |
||||||
199 | // Must have a supported encoding. |
||||||
200 | if (($encoding = mb_ord_chr_encoding($encoding)) === false) |
||||||
201 | return false; |
||||||
202 | |||||||
203 | /* Alternative approach for certain encodings. |
||||||
204 | * |
||||||
205 | * This is required because there are some invalid byte sequences in |
||||||
206 | * these encodings for which native mb_ord() will return false, yet |
||||||
207 | * mb_convert_encoding() and iconv() will nevertheless convert into |
||||||
208 | * technically valid but semantically unrelated UTF-8 byte sequences. |
||||||
209 | * |
||||||
210 | * For these encodings, mb_encode_numericentity() always produces |
||||||
211 | * either an entity with the same number that mb_ord() would produce, |
||||||
212 | * or else malformed output for byte sequences where mb_ord() would |
||||||
213 | * return false. This allows us to use mb_encode_numericentity() as a |
||||||
214 | * (slow) alternative method for these encodings. |
||||||
215 | * |
||||||
216 | * Note: we cannot use mb_check_encoding() here, because it returns |
||||||
217 | * false for ALL invalid byte sequences, but mb_ord() only returns false |
||||||
218 | * for SOME invalid byte sequences. |
||||||
219 | */ |
||||||
220 | if (in_array($encoding, array('EUC-CN', 'EUC-KR', 'ISO-2022-KR'))) |
||||||
221 | { |
||||||
222 | if (!function_exists('mb_encode_numericentity')) |
||||||
223 | return false; |
||||||
224 | |||||||
225 | $entity = mb_encode_numericentity($string, array(0x0,0x10FFFF,0x0,0xFFFFFF), $encoding); |
||||||
0 ignored issues
–
show
It seems like
$encoding can also be of type true ; however, parameter $encoding of mb_encode_numericentity() does only seem to accept null|string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
226 | |||||||
227 | if (strpos($entity, '&#') !== 0) |
||||||
228 | return false; |
||||||
229 | |||||||
230 | return (int) trim($entity, '&#;'); |
||||||
231 | } |
||||||
232 | |||||||
233 | // Convert to UTF-8. Return false on failure. |
||||||
234 | if ($encoding !== 'UTF-8') |
||||||
235 | { |
||||||
236 | $temp = false; |
||||||
237 | |||||||
238 | if (function_exists('mb_convert_encoding')) |
||||||
239 | { |
||||||
240 | $mb_substitute_character = mb_substitute_character(); |
||||||
241 | mb_substitute_character('none'); |
||||||
242 | |||||||
243 | $temp = mb_convert_encoding($string, 'UTF-8', $encoding); |
||||||
0 ignored issues
–
show
It seems like
$encoding can also be of type true ; however, parameter $from_encoding of mb_convert_encoding() does only seem to accept array|null|string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
244 | |||||||
245 | mb_substitute_character($mb_substitute_character); |
||||||
0 ignored issues
–
show
It seems like
$mb_substitute_character can also be of type true ; however, parameter $substitute_character of mb_substitute_character() does only seem to accept integer|null|string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
246 | } |
||||||
247 | |||||||
248 | if ($temp === false && function_exists('iconv')) |
||||||
249 | $temp = iconv($encoding, 'UTF-8', $string); |
||||||
0 ignored issues
–
show
It seems like
$encoding can also be of type true ; however, parameter $from_encoding of iconv() does only seem to accept string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
250 | |||||||
251 | if ($temp === false) |
||||||
252 | return false; |
||||||
253 | |||||||
254 | $string = $temp; |
||||||
255 | } |
||||||
256 | |||||||
257 | if (strlen($string) === 1) |
||||||
258 | return ord($string); |
||||||
259 | |||||||
260 | // Get the values of the individual bytes. |
||||||
261 | $unpacked = unpack('C*', substr($string, 0, 4)); |
||||||
262 | |||||||
263 | if ($unpacked === false) |
||||||
264 | { |
||||||
265 | $ord = 0; |
||||||
266 | } |
||||||
267 | elseif ($unpacked[1] >= 0xF0) |
||||||
268 | { |
||||||
269 | $ord = ($unpacked[1] - 0xF0) << 18; |
||||||
270 | $ord += ($unpacked[2] - 0x80) << 12; |
||||||
271 | $ord += ($unpacked[3] - 0x80) << 6; |
||||||
272 | $ord += $unpacked[4] - 0x80; |
||||||
273 | } |
||||||
274 | elseif ($unpacked[1] >= 0xE0) |
||||||
275 | { |
||||||
276 | $ord = ($unpacked[1] - 0xE0) << 12; |
||||||
277 | $ord += ($unpacked[2] - 0x80) << 6; |
||||||
278 | $ord += $unpacked[3] - 0x80; |
||||||
279 | } |
||||||
280 | elseif ($unpacked[1] >= 0xC0) |
||||||
281 | { |
||||||
282 | $ord = ($unpacked[1] - 0xC0) << 6; |
||||||
283 | $ord += $unpacked[2] - 0x80; |
||||||
284 | } |
||||||
285 | else |
||||||
286 | { |
||||||
287 | $ord = $unpacked[1]; |
||||||
288 | } |
||||||
289 | |||||||
290 | // Surrogate pairs are invalid in UTF-8. |
||||||
291 | if ($ord >= 0xD800 && $ord <= 0xDFFF) |
||||||
292 | $ord = 0; |
||||||
293 | |||||||
294 | return $ord; |
||||||
295 | } |
||||||
296 | } |
||||||
297 | |||||||
298 | if (!function_exists('mb_chr')) |
||||||
299 | { |
||||||
300 | /** |
||||||
301 | * Compatibility function. |
||||||
302 | * |
||||||
303 | * This is a complete polyfill. |
||||||
304 | * |
||||||
305 | * @param int $codepoint A Unicode codepoint value. |
||||||
306 | * @param string|null $encoding The character encoding. |
||||||
307 | * If null, the current SMF encoding will be used, falling back to UTF-8. |
||||||
308 | * @return string|bool The requested character, or false on failure. |
||||||
309 | */ |
||||||
310 | function mb_chr($codepoint, $encoding = null) |
||||||
311 | { |
||||||
312 | // Must have a supported encoding. |
||||||
313 | if (($encoding = mb_ord_chr_encoding($encoding)) === false) |
||||||
314 | return false; |
||||||
315 | |||||||
316 | // 0x10FFFF is the highest defined code point as of Unicode 13.0.0 |
||||||
317 | $codepoint %= 0x110000; |
||||||
318 | |||||||
319 | if ($codepoint < 0x80) |
||||||
320 | { |
||||||
321 | $string = chr($codepoint); |
||||||
322 | } |
||||||
323 | elseif ($codepoint < 0x800) |
||||||
324 | { |
||||||
325 | $string = chr(0xC0 | $codepoint >> 6) . chr(0x80 | $codepoint & 0x3F); |
||||||
326 | } |
||||||
327 | elseif ($codepoint < 0x10000) |
||||||
328 | { |
||||||
329 | $string = chr(0xE0 | $codepoint >> 12) . chr(0x80 | $codepoint >> 6 & 0x3F) . chr(0x80 | $codepoint & 0x3F); |
||||||
330 | } |
||||||
331 | else |
||||||
332 | { |
||||||
333 | $string = chr(0xF0 | $codepoint >> 18) . chr(0x80 | $codepoint >> 12 & 0x3F) . chr(0x80 | $codepoint >> 6 & 0x3F) . chr(0x80 | $codepoint & 0x3F); |
||||||
334 | } |
||||||
335 | |||||||
336 | // Return in the requested encoding, or false on failure. |
||||||
337 | // Note: native mb_chr() always returns a character in regular UTF-8 |
||||||
338 | // when the encoding is set to one of the UTF-8-Mobile* encodings. If |
||||||
339 | // that behaviour changes in the future, add version checks here. |
||||||
340 | if (strpos($encoding, 'UTF-8') !== 0) |
||||||
0 ignored issues
–
show
It seems like
$encoding can also be of type true ; however, parameter $haystack of strpos() does only seem to accept string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
341 | { |
||||||
342 | $temp = false; |
||||||
343 | |||||||
344 | if (function_exists('mb_convert_encoding')) |
||||||
345 | { |
||||||
346 | $mb_substitute_character = mb_substitute_character(); |
||||||
347 | mb_substitute_character('none'); |
||||||
348 | |||||||
349 | $temp = mb_convert_encoding($string, $encoding, 'UTF-8'); |
||||||
0 ignored issues
–
show
It seems like
$encoding can also be of type true ; however, parameter $to_encoding of mb_convert_encoding() does only seem to accept string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
350 | |||||||
351 | mb_substitute_character($mb_substitute_character); |
||||||
0 ignored issues
–
show
It seems like
$mb_substitute_character can also be of type true ; however, parameter $substitute_character of mb_substitute_character() does only seem to accept integer|null|string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
352 | } |
||||||
353 | |||||||
354 | if ($temp === false && function_exists('iconv')) |
||||||
355 | $temp = iconv('UTF-8', $encoding, $string); |
||||||
0 ignored issues
–
show
It seems like
$encoding can also be of type true ; however, parameter $to_encoding of iconv() does only seem to accept string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
356 | |||||||
357 | if ($temp === false) |
||||||
358 | return false; |
||||||
359 | |||||||
360 | $string = $temp; |
||||||
361 | } |
||||||
362 | |||||||
363 | return $string; |
||||||
364 | } |
||||||
365 | } |
||||||
366 | |||||||
367 | /** |
||||||
368 | * Helper function for the mb_ord and mb_chr polyfills. |
||||||
369 | * |
||||||
370 | * Checks whether $encoding is a supported character encoding for the mb_ord |
||||||
371 | * and mb_chr functions. If $encoding is null, the current default character |
||||||
372 | * encoding is used. If the encoding is supported, it is returned as a string. |
||||||
373 | * If not, false is returned. |
||||||
374 | * |
||||||
375 | * @param string $encoding A character encoding to check, or null for default. |
||||||
376 | * @return string|bool The character encoding, or false if unsupported. |
||||||
377 | */ |
||||||
378 | function mb_ord_chr_encoding($encoding = null) |
||||||
379 | { |
||||||
380 | global $modSettings, $txt; |
||||||
381 | |||||||
382 | if (is_null($encoding)) |
||||||
383 | { |
||||||
384 | if (isset($modSettings['global_character_set'])) |
||||||
385 | $encoding = $modSettings['global_character_set']; |
||||||
386 | |||||||
387 | elseif (isset($txt['lang_character_set'])) |
||||||
388 | $encoding = $txt['lang_character_set']; |
||||||
389 | |||||||
390 | elseif (function_exists('mb_internal_encoding')) |
||||||
391 | $encoding = mb_internal_encoding(); |
||||||
392 | |||||||
393 | elseif (ini_get('default_charset') != false) |
||||||
0 ignored issues
–
show
|
|||||||
394 | $encoding = ini_get('default_charset'); |
||||||
395 | |||||||
396 | else |
||||||
397 | $encoding = 'UTF-8'; |
||||||
398 | } |
||||||
399 | |||||||
400 | // Only some mb_string encodings are supported by mb_chr() and mb_ord(). |
||||||
401 | $supported_encodings = array( |
||||||
402 | '8bit', 'UCS-4', 'UCS-4BE', 'UCS-4LE', 'UCS-2', 'UCS-2BE', 'UCS-2LE', |
||||||
403 | 'UTF-32', 'UTF-32BE', 'UTF-32LE', 'UTF-16', 'UTF-16BE', 'UTF-16LE', |
||||||
404 | 'UTF-8', 'ASCII', 'EUC-JP', 'SJIS', 'eucJP-win', 'EUC-JP-2004', |
||||||
405 | 'SJIS-win', 'SJIS-Mobile#DOCOMO', 'SJIS-Mobile#KDDI', |
||||||
406 | 'SJIS-Mobile#SOFTBANK', 'SJIS-mac', 'SJIS-2004', 'UTF-8-Mobile#DOCOMO', |
||||||
407 | 'UTF-8-Mobile#KDDI-A', 'UTF-8-Mobile#KDDI-B', 'UTF-8-Mobile#SOFTBANK', |
||||||
408 | 'CP932', 'CP51932', 'GB18030', 'Windows-1252', 'Windows-1254', |
||||||
409 | 'ISO-8859-1', 'ISO-8859-2', 'ISO-8859-3', 'ISO-8859-4', 'ISO-8859-5', |
||||||
410 | 'ISO-8859-6', 'ISO-8859-7', 'ISO-8859-8', 'ISO-8859-9', 'ISO-8859-10', |
||||||
411 | 'ISO-8859-13', 'ISO-8859-14', 'ISO-8859-15', 'ISO-8859-16', 'EUC-CN', |
||||||
412 | 'CP936', 'HZ', 'EUC-TW', 'BIG-5', 'CP950', 'EUC-KR', 'UHC', |
||||||
413 | 'ISO-2022-KR', 'Windows-1251', 'CP866', 'KOI8-R', 'KOI8-U', 'ArmSCII-8', |
||||||
414 | 'CP850', 'JIS-ms', |
||||||
415 | ); |
||||||
416 | |||||||
417 | // Found it. |
||||||
418 | if (in_array($encoding, $supported_encodings)) |
||||||
419 | return $encoding; |
||||||
420 | |||||||
421 | // Gracefully handle aliases and incorrect lettercase. |
||||||
422 | $encoding_l = strtolower($encoding); |
||||||
423 | foreach ($supported_encodings as $possible_encoding) |
||||||
424 | { |
||||||
425 | $aliases = array_merge(array($possible_encoding), mb_encoding_aliases($possible_encoding)); |
||||||
426 | |||||||
427 | foreach ($aliases as $alias) |
||||||
428 | { |
||||||
429 | if (strtolower($alias) === $encoding_l) |
||||||
430 | return $possible_encoding; |
||||||
431 | } |
||||||
432 | } |
||||||
433 | |||||||
434 | return false; |
||||||
435 | } |
||||||
436 | |||||||
437 | /** |
||||||
438 | * IDNA_* constants used as flags for the idn_to_* functions. |
||||||
439 | */ |
||||||
440 | foreach ( |
||||||
441 | array( |
||||||
442 | 'IDNA_DEFAULT' => 0, |
||||||
443 | 'IDNA_ALLOW_UNASSIGNED' => 1, |
||||||
444 | 'IDNA_USE_STD3_RULES' => 2, |
||||||
445 | 'IDNA_CHECK_BIDI' => 4, |
||||||
446 | 'IDNA_CHECK_CONTEXTJ' => 8, |
||||||
447 | 'IDNA_NONTRANSITIONAL_TO_ASCII' => 16, |
||||||
448 | 'IDNA_NONTRANSITIONAL_TO_UNICODE' => 32, |
||||||
449 | 'INTL_IDNA_VARIANT_2003' => 0, |
||||||
450 | 'INTL_IDNA_VARIANT_UTS46' => 1, |
||||||
451 | ) |
||||||
452 | as $name => $value |
||||||
453 | ) |
||||||
454 | { |
||||||
455 | if (!defined($name)) |
||||||
456 | define($name, $value); |
||||||
457 | }; |
||||||
458 | |||||||
459 | if (!function_exists('idn_to_ascii')) |
||||||
460 | { |
||||||
461 | /** |
||||||
462 | * Compatibility function. |
||||||
463 | * |
||||||
464 | * This is not a complete polyfill: |
||||||
465 | * |
||||||
466 | * - $flags only supports IDNA_DEFAULT, IDNA_NONTRANSITIONAL_TO_ASCII, |
||||||
467 | * and IDNA_USE_STD3_RULES. |
||||||
468 | * - $variant is ignored, because INTL_IDNA_VARIANT_UTS46 is always used. |
||||||
469 | * - $idna_info is ignored. |
||||||
470 | * |
||||||
471 | * @param string $domain The domain to convert, which must be UTF-8 encoded. |
||||||
472 | * @param int $flags A subset of possible IDNA_* flags. |
||||||
473 | * @param int $variant Ignored in this compatibility function. |
||||||
474 | * @param array|null $idna_info Ignored in this compatibility function. |
||||||
475 | * @return string|bool The domain name encoded in ASCII-compatible form, or false on failure. |
||||||
476 | */ |
||||||
477 | function idn_to_ascii($domain, $flags = 0, $variant = 1, &$idna_info = null) |
||||||
0 ignored issues
–
show
The parameter
$variant is not used and could be removed.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for parameters that have been defined for a function or method, but which are not used in the method body. ![]() The parameter
$idna_info is not used and could be removed.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for parameters that have been defined for a function or method, but which are not used in the method body. ![]() |
|||||||
478 | { |
||||||
479 | global $sourcedir; |
||||||
480 | |||||||
481 | static $Punycode; |
||||||
482 | |||||||
483 | require_once($sourcedir . '/Class-Punycode.php'); |
||||||
484 | |||||||
485 | if (!is_object($Punycode)) |
||||||
486 | $Punycode = new Punycode(); |
||||||
487 | |||||||
488 | if (method_exists($Punycode, 'useStd3')) |
||||||
489 | $Punycode->useStd3($flags === ($flags | IDNA_USE_STD3_RULES)); |
||||||
490 | if (method_exists($Punycode, 'useNonTransitional')) |
||||||
491 | $Punycode->useNonTransitional($flags === ($flags | IDNA_NONTRANSITIONAL_TO_ASCII)); |
||||||
492 | |||||||
493 | return $Punycode->encode($domain); |
||||||
494 | } |
||||||
495 | } |
||||||
496 | |||||||
497 | if (!function_exists('idn_to_utf8')) |
||||||
498 | { |
||||||
499 | /** |
||||||
500 | * Compatibility function. |
||||||
501 | * |
||||||
502 | * This is not a complete polyfill: |
||||||
503 | * |
||||||
504 | * - $flags only supports IDNA_DEFAULT, IDNA_NONTRANSITIONAL_TO_UNICODE, |
||||||
505 | * and IDNA_USE_STD3_RULES. |
||||||
506 | * - $variant is ignored, because INTL_IDNA_VARIANT_UTS46 is always used. |
||||||
507 | * - $idna_info is ignored. |
||||||
508 | * |
||||||
509 | * @param string $domain Domain to convert, in an IDNA ASCII-compatible format. |
||||||
510 | * @param int $flags Ignored in this compatibility function. |
||||||
511 | * @param int $variant Ignored in this compatibility function. |
||||||
512 | * @param array|null $idna_info Ignored in this compatibility function. |
||||||
513 | * @return string|bool The domain name in Unicode, encoded in UTF-8, or false on failure. |
||||||
514 | */ |
||||||
515 | function idn_to_utf8($domain, $flags = 0, $variant = 1, &$idna_info = null) |
||||||
0 ignored issues
–
show
The parameter
$idna_info is not used and could be removed.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for parameters that have been defined for a function or method, but which are not used in the method body. ![]() The parameter
$variant is not used and could be removed.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for parameters that have been defined for a function or method, but which are not used in the method body. ![]() |
|||||||
516 | { |
||||||
517 | global $sourcedir; |
||||||
518 | |||||||
519 | static $Punycode; |
||||||
520 | |||||||
521 | require_once($sourcedir . '/Class-Punycode.php'); |
||||||
522 | |||||||
523 | if (!is_object($Punycode)) |
||||||
524 | $Punycode = new Punycode(); |
||||||
525 | |||||||
526 | $Punycode->useStd3($flags === ($flags | IDNA_USE_STD3_RULES)); |
||||||
527 | $Punycode->useNonTransitional($flags === ($flags | IDNA_NONTRANSITIONAL_TO_UNICODE)); |
||||||
528 | |||||||
529 | return $Punycode->decode($domain); |
||||||
530 | } |
||||||
531 | } |
||||||
532 | |||||||
533 | /** |
||||||
534 | * Prevent fatal errors under PHP 8 when a disabled internal function is called. |
||||||
535 | * |
||||||
536 | * Before PHP 8, calling a disabled internal function merely generated a |
||||||
537 | * warning that could be easily suppressed by the @ operator. But as of PHP 8 |
||||||
538 | * a disabled internal function is treated like it is undefined, which means |
||||||
539 | * a fatal error will be thrown and execution will halt. SMF expects the old |
||||||
540 | * behaviour, so these no-op polyfills make sure that is what happens. |
||||||
541 | */ |
||||||
542 | if (version_compare(PHP_VERSION, '8.0.0', '>=')) |
||||||
543 | { |
||||||
544 | /* |
||||||
545 | * This array contains function names that meet the following conditions: |
||||||
546 | * |
||||||
547 | * 1. SMF assumes they are defined, even if disabled. Note that prior to |
||||||
548 | * PHP 8, this was always true for internal functions. |
||||||
549 | * |
||||||
550 | * 2. Some hosts are known to disable them. |
||||||
551 | * |
||||||
552 | * 3. SMF can get by without them (as opposed to missing functions that |
||||||
553 | * really SHOULD cause execution to halt). |
||||||
554 | */ |
||||||
555 | foreach (array('set_time_limit') as $func) |
||||||
556 | { |
||||||
557 | if (!function_exists($func)) |
||||||
558 | eval('function ' . $func . '() { trigger_error("' . $func . '() has been disabled for security reasons", E_USER_WARNING); }'); |
||||||
0 ignored issues
–
show
|
|||||||
559 | } |
||||||
560 | unset($func); |
||||||
561 | } |
||||||
562 | |||||||
563 | ?> |