256 |
261 |
257 // Fencepost: preg_split() always returns one extra item in the array. |
262 // Fencepost: preg_split() always returns one extra item in the array. |
258 return --$count; |
263 return --$count; |
259 } |
264 } |
260 |
265 |
261 if ( ! function_exists( 'hash_hmac' ) ) : |
|
262 /** |
|
263 * Compat function to mimic hash_hmac(). |
|
264 * |
|
265 * The Hash extension is bundled with PHP by default since PHP 5.1.2. |
|
266 * However, the extension may be explicitly disabled on select servers. |
|
267 * As of PHP 7.4.0, the Hash extension is a core PHP extension and can no |
|
268 * longer be disabled. |
|
269 * I.e. when PHP 7.4.0 becomes the minimum requirement, this polyfill |
|
270 * and the associated `_hash_hmac()` function can be safely removed. |
|
271 * |
|
272 * @ignore |
|
273 * @since 3.2.0 |
|
274 * |
|
275 * @see _hash_hmac() |
|
276 * |
|
277 * @param string $algo Hash algorithm. Accepts 'md5' or 'sha1'. |
|
278 * @param string $data Data to be hashed. |
|
279 * @param string $key Secret key to use for generating the hash. |
|
280 * @param bool $binary Optional. Whether to output raw binary data (true), |
|
281 * or lowercase hexits (false). Default false. |
|
282 * @return string|false The hash in output determined by `$binary`. |
|
283 * False if `$algo` is unknown or invalid. |
|
284 */ |
|
285 function hash_hmac( $algo, $data, $key, $binary = false ) { |
|
286 return _hash_hmac( $algo, $data, $key, $binary ); |
|
287 } |
|
288 endif; |
|
289 |
|
290 /** |
|
291 * Internal compat function to mimic hash_hmac(). |
|
292 * |
|
293 * @ignore |
|
294 * @since 3.2.0 |
|
295 * |
|
296 * @param string $algo Hash algorithm. Accepts 'md5' or 'sha1'. |
|
297 * @param string $data Data to be hashed. |
|
298 * @param string $key Secret key to use for generating the hash. |
|
299 * @param bool $binary Optional. Whether to output raw binary data (true), |
|
300 * or lowercase hexits (false). Default false. |
|
301 * @return string|false The hash in output determined by `$binary`. |
|
302 * False if `$algo` is unknown or invalid. |
|
303 */ |
|
304 function _hash_hmac( $algo, $data, $key, $binary = false ) { |
|
305 $packs = array( |
|
306 'md5' => 'H32', |
|
307 'sha1' => 'H40', |
|
308 ); |
|
309 |
|
310 if ( ! isset( $packs[ $algo ] ) ) { |
|
311 return false; |
|
312 } |
|
313 |
|
314 $pack = $packs[ $algo ]; |
|
315 |
|
316 if ( strlen( $key ) > 64 ) { |
|
317 $key = pack( $pack, $algo( $key ) ); |
|
318 } |
|
319 |
|
320 $key = str_pad( $key, 64, chr( 0 ) ); |
|
321 |
|
322 $ipad = ( substr( $key, 0, 64 ) ^ str_repeat( chr( 0x36 ), 64 ) ); |
|
323 $opad = ( substr( $key, 0, 64 ) ^ str_repeat( chr( 0x5C ), 64 ) ); |
|
324 |
|
325 $hmac = $algo( $opad . pack( $pack, $algo( $ipad . $data ) ) ); |
|
326 |
|
327 if ( $binary ) { |
|
328 return pack( $pack, $hmac ); |
|
329 } |
|
330 |
|
331 return $hmac; |
|
332 } |
|
333 |
|
334 if ( ! function_exists( 'hash_equals' ) ) : |
|
335 /** |
|
336 * Timing attack safe string comparison. |
|
337 * |
|
338 * Compares two strings using the same time whether they're equal or not. |
|
339 * |
|
340 * Note: It can leak the length of a string when arguments of differing length are supplied. |
|
341 * |
|
342 * This function was added in PHP 5.6. |
|
343 * However, the Hash extension may be explicitly disabled on select servers. |
|
344 * As of PHP 7.4.0, the Hash extension is a core PHP extension and can no |
|
345 * longer be disabled. |
|
346 * I.e. when PHP 7.4.0 becomes the minimum requirement, this polyfill |
|
347 * can be safely removed. |
|
348 * |
|
349 * @since 3.9.2 |
|
350 * |
|
351 * @param string $known_string Expected string. |
|
352 * @param string $user_string Actual, user supplied, string. |
|
353 * @return bool Whether strings are equal. |
|
354 */ |
|
355 function hash_equals( $known_string, $user_string ) { |
|
356 $known_string_length = strlen( $known_string ); |
|
357 |
|
358 if ( strlen( $user_string ) !== $known_string_length ) { |
|
359 return false; |
|
360 } |
|
361 |
|
362 $result = 0; |
|
363 |
|
364 // Do not attempt to "optimize" this. |
|
365 for ( $i = 0; $i < $known_string_length; $i++ ) { |
|
366 $result |= ord( $known_string[ $i ] ) ^ ord( $user_string[ $i ] ); |
|
367 } |
|
368 |
|
369 return 0 === $result; |
|
370 } |
|
371 endif; |
|
372 |
|
373 // sodium_crypto_box() was introduced in PHP 7.2. |
266 // sodium_crypto_box() was introduced in PHP 7.2. |
374 if ( ! function_exists( 'sodium_crypto_box' ) ) { |
267 if ( ! function_exists( 'sodium_crypto_box' ) ) { |
375 require ABSPATH . WPINC . '/sodium_compat/autoload.php'; |
268 require ABSPATH . WPINC . '/sodium_compat/autoload.php'; |
376 } |
269 } |
377 |
270 |
538 |
435 |
539 return substr( $haystack, -$len, $len ) === $needle; |
436 return substr( $haystack, -$len, $len ) === $needle; |
540 } |
437 } |
541 } |
438 } |
542 |
439 |
|
440 if ( ! function_exists( 'array_find' ) ) { |
|
441 /** |
|
442 * Polyfill for `array_find()` function added in PHP 8.4. |
|
443 * |
|
444 * Searches an array for the first element that passes a given callback. |
|
445 * |
|
446 * @since 6.8.0 |
|
447 * |
|
448 * @param array $array The array to search. |
|
449 * @param callable $callback The callback to run for each element. |
|
450 * @return mixed|null The first element in the array that passes the `$callback`, otherwise null. |
|
451 */ |
|
452 function array_find( array $array, callable $callback ) { // phpcs:ignore Universal.NamingConventions.NoReservedKeywordParameterNames.arrayFound |
|
453 foreach ( $array as $key => $value ) { |
|
454 if ( $callback( $value, $key ) ) { |
|
455 return $value; |
|
456 } |
|
457 } |
|
458 |
|
459 return null; |
|
460 } |
|
461 } |
|
462 |
|
463 if ( ! function_exists( 'array_find_key' ) ) { |
|
464 /** |
|
465 * Polyfill for `array_find_key()` function added in PHP 8.4. |
|
466 * |
|
467 * Searches an array for the first key that passes a given callback. |
|
468 * |
|
469 * @since 6.8.0 |
|
470 * |
|
471 * @param array $array The array to search. |
|
472 * @param callable $callback The callback to run for each element. |
|
473 * @return int|string|null The first key in the array that passes the `$callback`, otherwise null. |
|
474 */ |
|
475 function array_find_key( array $array, callable $callback ) { // phpcs:ignore Universal.NamingConventions.NoReservedKeywordParameterNames.arrayFound |
|
476 foreach ( $array as $key => $value ) { |
|
477 if ( $callback( $value, $key ) ) { |
|
478 return $key; |
|
479 } |
|
480 } |
|
481 |
|
482 return null; |
|
483 } |
|
484 } |
|
485 |
|
486 if ( ! function_exists( 'array_any' ) ) { |
|
487 /** |
|
488 * Polyfill for `array_any()` function added in PHP 8.4. |
|
489 * |
|
490 * Checks if any element of an array passes a given callback. |
|
491 * |
|
492 * @since 6.8.0 |
|
493 * |
|
494 * @param array $array The array to check. |
|
495 * @param callable $callback The callback to run for each element. |
|
496 * @return bool True if any element in the array passes the `$callback`, otherwise false. |
|
497 */ |
|
498 function array_any( array $array, callable $callback ): bool { // phpcs:ignore Universal.NamingConventions.NoReservedKeywordParameterNames.arrayFound |
|
499 foreach ( $array as $key => $value ) { |
|
500 if ( $callback( $value, $key ) ) { |
|
501 return true; |
|
502 } |
|
503 } |
|
504 |
|
505 return false; |
|
506 } |
|
507 } |
|
508 |
|
509 if ( ! function_exists( 'array_all' ) ) { |
|
510 /** |
|
511 * Polyfill for `array_all()` function added in PHP 8.4. |
|
512 * |
|
513 * Checks if all elements of an array pass a given callback. |
|
514 * |
|
515 * @since 6.8.0 |
|
516 * |
|
517 * @param array $array The array to check. |
|
518 * @param callable $callback The callback to run for each element. |
|
519 * @return bool True if all elements in the array pass the `$callback`, otherwise false. |
|
520 */ |
|
521 function array_all( array $array, callable $callback ): bool { // phpcs:ignore Universal.NamingConventions.NoReservedKeywordParameterNames.arrayFound |
|
522 foreach ( $array as $key => $value ) { |
|
523 if ( ! $callback( $value, $key ) ) { |
|
524 return false; |
|
525 } |
|
526 } |
|
527 |
|
528 return true; |
|
529 } |
|
530 } |
|
531 |
543 // IMAGETYPE_AVIF constant is only defined in PHP 8.x or later. |
532 // IMAGETYPE_AVIF constant is only defined in PHP 8.x or later. |
544 if ( ! defined( 'IMAGETYPE_AVIF' ) ) { |
533 if ( ! defined( 'IMAGETYPE_AVIF' ) ) { |
545 define( 'IMAGETYPE_AVIF', 19 ); |
534 define( 'IMAGETYPE_AVIF', 19 ); |
546 } |
535 } |
547 |
536 |
548 // IMG_AVIF constant is only defined in PHP 8.x or later. |
537 // IMG_AVIF constant is only defined in PHP 8.x or later. |
549 if ( ! defined( 'IMG_AVIF' ) ) { |
538 if ( ! defined( 'IMG_AVIF' ) ) { |
550 define( 'IMG_AVIF', IMAGETYPE_AVIF ); |
539 define( 'IMG_AVIF', IMAGETYPE_AVIF ); |
551 } |
540 } |
|
541 |
|
542 // IMAGETYPE_HEIC constant is not yet defined in PHP as of PHP 8.3. |
|
543 if ( ! defined( 'IMAGETYPE_HEIC' ) ) { |
|
544 define( 'IMAGETYPE_HEIC', 99 ); |
|
545 } |