Ticket #42264: 42264.1.diff
File 42264.1.diff, 33.9 KB (added by , 6 years ago) |
---|
-
src/wp-includes/compat.php
diff --git src/wp-includes/compat.php src/wp-includes/compat.php index 7e37c30762..00c31d7bd5 100644
1 1 <?php 2 2 /** 3 * WordPress implementation for PHP functions either missing from older PHP versions or not included by default. 4 * 5 * @package PHP 6 * @access private 7 */ 8 9 // If gettext isn't available 10 if ( !function_exists('_') ) { 11 function _($string) { 12 return $string; 13 } 14 } 15 16 /** 17 * Returns whether PCRE/u (PCRE_UTF8 modifier) is available for use. 18 * 19 * @ignore 20 * @since 4.2.2 21 * @access private 22 * 23 * @staticvar string $utf8_pcre 24 * 25 * @param bool $set - Used for testing only 26 * null : default - get PCRE/u capability 27 * false : Used for testing - return false for future calls to this function 28 * 'reset': Used for testing - restore default behavior of this function 29 */ 30 function _wp_can_use_pcre_u( $set = null ) { 31 static $utf8_pcre = 'reset'; 32 33 if ( null !== $set ) { 34 $utf8_pcre = $set; 35 } 36 37 if ( 'reset' === $utf8_pcre ) { 38 $utf8_pcre = @preg_match( '/^./u', 'a' ); 39 } 40 41 return $utf8_pcre; 42 } 43 44 if ( ! function_exists( 'mb_substr' ) ) : 45 /** 46 * Compat function to mimic mb_substr(). 47 * 48 * @ignore 49 * @since 3.2.0 50 * 51 * @see _mb_substr() 52 * 53 * @param string $str The string to extract the substring from. 54 * @param int $start Position to being extraction from in `$str`. 55 * @param int|null $length Optional. Maximum number of characters to extract from `$str`. 56 * Default null. 57 * @param string|null $encoding Optional. Character encoding to use. Default null. 58 * @return string Extracted substring. 59 */ 60 function mb_substr( $str, $start, $length = null, $encoding = null ) { 61 return _mb_substr( $str, $start, $length, $encoding ); 62 } 63 endif; 64 65 /** 66 * Internal compat function to mimic mb_substr(). 67 * 68 * Only understands UTF-8 and 8bit. All other character sets will be treated as 8bit. 69 * For $encoding === UTF-8, the $str input is expected to be a valid UTF-8 byte sequence. 70 * The behavior of this function for invalid inputs is undefined. 71 * 72 * @ignore 73 * @since 3.2.0 74 * 75 * @param string $str The string to extract the substring from. 76 * @param int $start Position to being extraction from in `$str`. 77 * @param int|null $length Optional. Maximum number of characters to extract from `$str`. 78 * Default null. 79 * @param string|null $encoding Optional. Character encoding to use. Default null. 80 * @return string Extracted substring. 81 */ 82 function _mb_substr( $str, $start, $length = null, $encoding = null ) { 83 if ( null === $encoding ) { 84 $encoding = get_option( 'blog_charset' ); 85 } 86 87 /* 88 * The solution below works only for UTF-8, so in case of a different 89 * charset just use built-in substr(). 90 */ 91 if ( ! in_array( $encoding, array( 'utf8', 'utf-8', 'UTF8', 'UTF-8' ) ) ) { 92 return is_null( $length ) ? substr( $str, $start ) : substr( $str, $start, $length ); 93 } 94 95 if ( _wp_can_use_pcre_u() ) { 96 // Use the regex unicode support to separate the UTF-8 characters into an array. 97 preg_match_all( '/./us', $str, $match ); 98 $chars = is_null( $length ) ? array_slice( $match[0], $start ) : array_slice( $match[0], $start, $length ); 99 return implode( '', $chars ); 100 } 101 102 $regex = '/( 103 [\x00-\x7F] # single-byte sequences 0xxxxxxx 104 | [\xC2-\xDF][\x80-\xBF] # double-byte sequences 110xxxxx 10xxxxxx 105 | \xE0[\xA0-\xBF][\x80-\xBF] # triple-byte sequences 1110xxxx 10xxxxxx * 2 106 | [\xE1-\xEC][\x80-\xBF]{2} 107 | \xED[\x80-\x9F][\x80-\xBF] 108 | [\xEE-\xEF][\x80-\xBF]{2} 109 | \xF0[\x90-\xBF][\x80-\xBF]{2} # four-byte sequences 11110xxx 10xxxxxx * 3 110 | [\xF1-\xF3][\x80-\xBF]{3} 111 | \xF4[\x80-\x8F][\x80-\xBF]{2} 112 )/x'; 113 114 // Start with 1 element instead of 0 since the first thing we do is pop. 115 $chars = array( '' ); 116 do { 117 // We had some string left over from the last round, but we counted it in that last round. 118 array_pop( $chars ); 119 120 /* 121 * Split by UTF-8 character, limit to 1000 characters (last array element will contain 122 * the rest of the string). 123 */ 124 $pieces = preg_split( $regex, $str, 1000, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY ); 125 126 $chars = array_merge( $chars, $pieces ); 127 128 // If there's anything left over, repeat the loop. 129 } while ( count( $pieces ) > 1 && $str = array_pop( $pieces ) ); 130 131 return join( '', array_slice( $chars, $start, $length ) ); 132 } 133 134 if ( ! function_exists( 'mb_strlen' ) ) : 135 /** 136 * Compat function to mimic mb_strlen(). 137 * 138 * @ignore 139 * @since 4.2.0 140 * 141 * @see _mb_strlen() 142 * 143 * @param string $str The string to retrieve the character length from. 144 * @param string|null $encoding Optional. Character encoding to use. Default null. 145 * @return int String length of `$str`. 146 */ 147 function mb_strlen( $str, $encoding = null ) { 148 return _mb_strlen( $str, $encoding ); 149 } 150 endif; 151 152 /** 153 * Internal compat function to mimic mb_strlen(). 154 * 155 * Only understands UTF-8 and 8bit. All other character sets will be treated as 8bit. 156 * For $encoding === UTF-8, the `$str` input is expected to be a valid UTF-8 byte 157 * sequence. The behavior of this function for invalid inputs is undefined. 158 * 159 * @ignore 160 * @since 4.2.0 161 * 162 * @param string $str The string to retrieve the character length from. 163 * @param string|null $encoding Optional. Character encoding to use. Default null. 164 * @return int String length of `$str`. 165 */ 166 function _mb_strlen( $str, $encoding = null ) { 167 if ( null === $encoding ) { 168 $encoding = get_option( 'blog_charset' ); 169 } 170 171 /* 172 * The solution below works only for UTF-8, so in case of a different charset 173 * just use built-in strlen(). 174 */ 175 if ( ! in_array( $encoding, array( 'utf8', 'utf-8', 'UTF8', 'UTF-8' ) ) ) { 176 return strlen( $str ); 177 } 178 179 if ( _wp_can_use_pcre_u() ) { 180 // Use the regex unicode support to separate the UTF-8 characters into an array. 181 preg_match_all( '/./us', $str, $match ); 182 return count( $match[0] ); 183 } 184 185 $regex = '/(?: 186 [\x00-\x7F] # single-byte sequences 0xxxxxxx 187 | [\xC2-\xDF][\x80-\xBF] # double-byte sequences 110xxxxx 10xxxxxx 188 | \xE0[\xA0-\xBF][\x80-\xBF] # triple-byte sequences 1110xxxx 10xxxxxx * 2 189 | [\xE1-\xEC][\x80-\xBF]{2} 190 | \xED[\x80-\x9F][\x80-\xBF] 191 | [\xEE-\xEF][\x80-\xBF]{2} 192 | \xF0[\x90-\xBF][\x80-\xBF]{2} # four-byte sequences 11110xxx 10xxxxxx * 3 193 | [\xF1-\xF3][\x80-\xBF]{3} 194 | \xF4[\x80-\x8F][\x80-\xBF]{2} 195 )/x'; 196 197 // Start at 1 instead of 0 since the first thing we do is decrement. 198 $count = 1; 199 do { 200 // We had some string left over from the last round, but we counted it in that last round. 201 $count--; 202 203 /* 204 * Split by UTF-8 character, limit to 1000 characters (last array element will contain 205 * the rest of the string). 206 */ 207 $pieces = preg_split( $regex, $str, 1000 ); 208 209 // Increment. 210 $count += count( $pieces ); 211 212 // If there's anything left over, repeat the loop. 213 } while ( $str = array_pop( $pieces ) ); 214 215 // Fencepost: preg_split() always returns one extra item in the array. 216 return --$count; 217 } 218 219 if ( !function_exists('hash_hmac') ): 220 /** 221 * Compat function to mimic hash_hmac(). 222 * 223 * @ignore 224 * @since 3.2.0 225 * 226 * @see _hash_hmac() 227 * 228 * @param string $algo Hash algorithm. Accepts 'md5' or 'sha1'. 229 * @param string $data Data to be hashed. 230 * @param string $key Secret key to use for generating the hash. 231 * @param bool $raw_output Optional. Whether to output raw binary data (true), 232 * or lowercase hexits (false). Default false. 233 * @return string|false The hash in output determined by `$raw_output`. False if `$algo` 234 * is unknown or invalid. 235 */ 236 function hash_hmac($algo, $data, $key, $raw_output = false) { 237 return _hash_hmac($algo, $data, $key, $raw_output); 238 } 239 endif; 240 241 /** 242 * Internal compat function to mimic hash_hmac(). 243 * 244 * @ignore 245 * @since 3.2.0 246 * 247 * @param string $algo Hash algorithm. Accepts 'md5' or 'sha1'. 248 * @param string $data Data to be hashed. 249 * @param string $key Secret key to use for generating the hash. 250 * @param bool $raw_output Optional. Whether to output raw binary data (true), 251 * or lowercase hexits (false). Default false. 252 * @return string|false The hash in output determined by `$raw_output`. False if `$algo` 253 * is unknown or invalid. 254 */ 255 function _hash_hmac($algo, $data, $key, $raw_output = false) { 256 $packs = array('md5' => 'H32', 'sha1' => 'H40'); 257 258 if ( !isset($packs[$algo]) ) 259 return false; 260 261 $pack = $packs[$algo]; 262 263 if (strlen($key) > 64) 264 $key = pack($pack, $algo($key)); 265 266 $key = str_pad($key, 64, chr(0)); 267 268 $ipad = (substr($key, 0, 64) ^ str_repeat(chr(0x36), 64)); 269 $opad = (substr($key, 0, 64) ^ str_repeat(chr(0x5C), 64)); 270 271 $hmac = $algo($opad . pack($pack, $algo($ipad . $data))); 272 273 if ( $raw_output ) 274 return pack( $pack, $hmac ); 275 return $hmac; 276 } 277 278 if ( !function_exists('json_encode') ) { 279 function json_encode( $string ) { 280 global $wp_json; 281 282 if ( ! ( $wp_json instanceof Services_JSON ) ) { 283 require_once( ABSPATH . WPINC . '/class-json.php' ); 284 $wp_json = new Services_JSON(); 285 } 286 287 return $wp_json->encodeUnsafe( $string ); 288 } 289 } 290 291 if ( !function_exists('json_decode') ) { 292 /** 293 * @global Services_JSON $wp_json 294 * @param string $string 295 * @param bool $assoc_array 296 * @return object|array 297 */ 298 function json_decode( $string, $assoc_array = false ) { 299 global $wp_json; 300 301 if ( ! ($wp_json instanceof Services_JSON ) ) { 302 require_once( ABSPATH . WPINC . '/class-json.php' ); 303 $wp_json = new Services_JSON(); 304 } 305 306 $res = $wp_json->decode( $string ); 307 if ( $assoc_array ) 308 $res = _json_decode_object_helper( $res ); 309 return $res; 310 } 311 312 /** 313 * @param object $data 314 * @return array 315 */ 316 function _json_decode_object_helper($data) { 317 if ( is_object($data) ) 318 $data = get_object_vars($data); 319 return is_array($data) ? array_map(__FUNCTION__, $data) : $data; 320 } 321 } 322 323 if ( ! function_exists( 'hash_equals' ) ) : 324 /** 325 * Timing attack safe string comparison 326 * 327 * Compares two strings using the same time whether they're equal or not. 328 * 329 * This function was added in PHP 5.6. 330 * 331 * Note: It can leak the length of a string when arguments of differing length are supplied. 332 * 333 * @since 3.9.2 334 * 335 * @param string $a Expected string. 336 * @param string $b Actual, user supplied, string. 337 * @return bool Whether strings are equal. 338 */ 339 function hash_equals( $a, $b ) { 340 $a_length = strlen( $a ); 341 if ( $a_length !== strlen( $b ) ) { 342 return false; 343 } 344 $result = 0; 345 346 // Do not attempt to "optimize" this. 347 for ( $i = 0; $i < $a_length; $i++ ) { 348 $result |= ord( $a[ $i ] ) ^ ord( $b[ $i ] ); 349 } 350 351 return $result === 0; 352 } 353 endif; 354 355 // JSON_PRETTY_PRINT was introduced in PHP 5.4 356 // Defined here to prevent a notice when using it with wp_json_encode() 357 if ( ! defined( 'JSON_PRETTY_PRINT' ) ) { 358 define( 'JSON_PRETTY_PRINT', 128 ); 359 } 360 361 if ( ! function_exists( 'json_last_error_msg' ) ) : 362 /** 363 * Retrieves the error string of the last json_encode() or json_decode() call. 364 * 365 * @since 4.4.0 366 * 367 * @internal This is a compatibility function for PHP <5.5 368 * 369 * @return bool|string Returns the error message on success, "No Error" if no error has occurred, 370 * or false on failure. 371 */ 372 function json_last_error_msg() { 373 // See https://core.trac.wordpress.org/ticket/27799. 374 if ( ! function_exists( 'json_last_error' ) ) { 375 return false; 376 } 377 378 $last_error_code = json_last_error(); 379 380 // Just in case JSON_ERROR_NONE is not defined. 381 $error_code_none = defined( 'JSON_ERROR_NONE' ) ? JSON_ERROR_NONE : 0; 382 383 switch ( true ) { 384 case $last_error_code === $error_code_none: 385 return 'No error'; 386 387 case defined( 'JSON_ERROR_DEPTH' ) && JSON_ERROR_DEPTH === $last_error_code: 388 return 'Maximum stack depth exceeded'; 389 390 case defined( 'JSON_ERROR_STATE_MISMATCH' ) && JSON_ERROR_STATE_MISMATCH === $last_error_code: 391 return 'State mismatch (invalid or malformed JSON)'; 392 393 case defined( 'JSON_ERROR_CTRL_CHAR' ) && JSON_ERROR_CTRL_CHAR === $last_error_code: 394 return 'Control character error, possibly incorrectly encoded'; 395 396 case defined( 'JSON_ERROR_SYNTAX' ) && JSON_ERROR_SYNTAX === $last_error_code: 397 return 'Syntax error'; 398 399 case defined( 'JSON_ERROR_UTF8' ) && JSON_ERROR_UTF8 === $last_error_code: 400 return 'Malformed UTF-8 characters, possibly incorrectly encoded'; 401 402 case defined( 'JSON_ERROR_RECURSION' ) && JSON_ERROR_RECURSION === $last_error_code: 403 return 'Recursion detected'; 404 405 case defined( 'JSON_ERROR_INF_OR_NAN' ) && JSON_ERROR_INF_OR_NAN === $last_error_code: 406 return 'Inf and NaN cannot be JSON encoded'; 407 408 case defined( 'JSON_ERROR_UNSUPPORTED_TYPE' ) && JSON_ERROR_UNSUPPORTED_TYPE === $last_error_code: 409 return 'Type is not supported'; 410 411 default: 412 return 'An unknown error occurred'; 413 } 414 } 415 endif; 416 417 if ( ! interface_exists( 'JsonSerializable' ) ) { 418 define( 'WP_JSON_SERIALIZE_COMPATIBLE', true ); 419 /** 420 * JsonSerializable interface. 421 * 422 * Compatibility shim for PHP <5.4 423 * 424 * @link https://secure.php.net/jsonserializable 425 * 426 * @since 4.4.0 427 */ 428 interface JsonSerializable { 429 public function jsonSerialize(); 430 } 431 } 432 433 // random_int was introduced in PHP 7.0 434 if ( ! function_exists( 'random_int' ) ) { 435 require ABSPATH . WPINC . '/random_compat/random.php'; 436 } 437 438 if ( ! function_exists( 'array_replace_recursive' ) ) : 439 /** 440 * PHP-agnostic version of {@link array_replace_recursive()}. 441 * 442 * The array_replace_recursive() function is a PHP 5.3 function. WordPress 443 * currently supports down to PHP 5.2, so this method is a workaround 444 * for PHP 5.2. 445 * 446 * Note: array_replace_recursive() supports infinite arguments, but for our use- 447 * case, we only need to support two arguments. 448 * 449 * Subject to removal once WordPress makes PHP 5.3.0 the minimum requirement. 450 * 451 * @since 4.5.3 452 * 453 * @see https://secure.php.net/manual/en/function.array-replace-recursive.php#109390 454 * 455 * @param array $base Array with keys needing to be replaced. 456 * @param array $replacements Array with the replaced keys. 457 * 458 * @return array 459 */ 460 function array_replace_recursive( $base = array(), $replacements = array() ) { 461 foreach ( array_slice( func_get_args(), 1 ) as $replacements ) { 462 $bref_stack = array( &$base ); 463 $head_stack = array( $replacements ); 464 465 do { 466 end( $bref_stack ); 467 468 $bref = &$bref_stack[ key( $bref_stack ) ]; 469 $head = array_pop( $head_stack ); 470 471 unset( $bref_stack[ key( $bref_stack ) ] ); 472 473 foreach ( array_keys( $head ) as $key ) { 474 if ( isset( $key, $bref ) && 475 isset( $bref[ $key ] ) && is_array( $bref[ $key ] ) && 476 isset( $head[ $key ] ) && is_array( $head[ $key ] ) 477 ) { 478 $bref_stack[] = &$bref[ $key ]; 479 $head_stack[] = $head[ $key ]; 480 } else { 481 $bref[ $key ] = $head[ $key ]; 482 } 483 } 484 } while ( count( $head_stack ) ); 485 } 486 487 return $base; 488 } 489 endif; 490 491 /** 492 * Polyfill for the SPL autoloader. In PHP 5.2 (but not 5.3 and later), SPL can 493 * be disabled, and PHP 7.2 raises notices if the compiler finds an __autoload() 494 * function declaration. Function availability is checked here, and the 495 * autoloader is included only if necessary. 496 */ 497 if ( ! function_exists( 'spl_autoload_register' ) ) { 498 require_once ABSPATH . WPINC . '/spl-autoload-compat.php'; 3 * WordPress compatiblity logic. 4 */ 5 6 // Check the PHP version and load the corresponding compatibility files. 7 // The fall-throughs (missing breaks) are intentional, as this makes sure that 8 // all compat files - starting from the first required one - will be loaded. 9 switch ( substr( PHP_VERSION, 0, 3 ) ) { 10 case '5.2': 11 require ABSPATH . WPINC . '/compat/php-5.2.php'; 12 case '5.3': 13 require ABSPATH . WPINC . '/compat/php-5.3.php'; 14 case '5.4': 15 require ABSPATH . WPINC . '/compat/php-5.4.php'; 16 case '5.5': 17 require ABSPATH . WPINC . '/compat/php-5.5.php'; 18 case '5.6': 19 require ABSPATH . WPINC . '/compat/php-5.6.php'; 20 case '7.0': 21 require ABSPATH . WPINC . '/compat/php-7.0.php'; 22 case '7.1': 23 require ABSPATH . WPINC . '/compat/php-7.1.php'; 24 case '7.2': 25 require ABSPATH . WPINC . '/compat/php-7.2.php'; 26 default: 27 require ABSPATH . WPINC . '/compat/default.php'; 499 28 } -
new file src/wp-includes/compat/default.php
diff --git src/wp-includes/compat/default.php src/wp-includes/compat/default.php new file mode 100644 index 0000000000..bf1f2f01ba
- + 1 <?php 2 /** 3 * WordPress implementation for PHP functions either missing from older PHP versions or not included by default. 4 * 5 * @package PHP 6 * @access private 7 */ 8 9 // If gettext isn't available 10 if ( !function_exists('_') ) { 11 function _($string) { 12 return $string; 13 } 14 } 15 16 /** 17 * Returns whether PCRE/u (PCRE_UTF8 modifier) is available for use. 18 * 19 * @ignore 20 * @since 4.2.2 21 * @access private 22 * 23 * @staticvar string $utf8_pcre 24 * 25 * @param bool $set - Used for testing only 26 * null : default - get PCRE/u capability 27 * false : Used for testing - return false for future calls to this function 28 * 'reset': Used for testing - restore default behavior of this function 29 */ 30 function _wp_can_use_pcre_u( $set = null ) { 31 static $utf8_pcre = 'reset'; 32 33 if ( null !== $set ) { 34 $utf8_pcre = $set; 35 } 36 37 if ( 'reset' === $utf8_pcre ) { 38 $utf8_pcre = @preg_match( '/^./u', 'a' ); 39 } 40 41 return $utf8_pcre; 42 } 43 44 if ( ! function_exists( 'mb_substr' ) ) : 45 /** 46 * Compat function to mimic mb_substr(). 47 * 48 * @ignore 49 * @since 3.2.0 50 * 51 * @see _mb_substr() 52 * 53 * @param string $str The string to extract the substring from. 54 * @param int $start Position to being extraction from in `$str`. 55 * @param int|null $length Optional. Maximum number of characters to extract from `$str`. 56 * Default null. 57 * @param string|null $encoding Optional. Character encoding to use. Default null. 58 * @return string Extracted substring. 59 */ 60 function mb_substr( $str, $start, $length = null, $encoding = null ) { 61 return _mb_substr( $str, $start, $length, $encoding ); 62 } 63 endif; 64 65 /** 66 * Internal compat function to mimic mb_substr(). 67 * 68 * Only understands UTF-8 and 8bit. All other character sets will be treated as 8bit. 69 * For $encoding === UTF-8, the $str input is expected to be a valid UTF-8 byte sequence. 70 * The behavior of this function for invalid inputs is undefined. 71 * 72 * @ignore 73 * @since 3.2.0 74 * 75 * @param string $str The string to extract the substring from. 76 * @param int $start Position to being extraction from in `$str`. 77 * @param int|null $length Optional. Maximum number of characters to extract from `$str`. 78 * Default null. 79 * @param string|null $encoding Optional. Character encoding to use. Default null. 80 * @return string Extracted substring. 81 */ 82 function _mb_substr( $str, $start, $length = null, $encoding = null ) { 83 if ( null === $encoding ) { 84 $encoding = get_option( 'blog_charset' ); 85 } 86 87 /* 88 * The solution below works only for UTF-8, so in case of a different 89 * charset just use built-in substr(). 90 */ 91 if ( ! in_array( $encoding, array( 'utf8', 'utf-8', 'UTF8', 'UTF-8' ) ) ) { 92 return is_null( $length ) ? substr( $str, $start ) : substr( $str, $start, $length ); 93 } 94 95 if ( _wp_can_use_pcre_u() ) { 96 // Use the regex unicode support to separate the UTF-8 characters into an array. 97 preg_match_all( '/./us', $str, $match ); 98 $chars = is_null( $length ) ? array_slice( $match[0], $start ) : array_slice( $match[0], $start, $length ); 99 return implode( '', $chars ); 100 } 101 102 $regex = '/( 103 [\x00-\x7F] # single-byte sequences 0xxxxxxx 104 | [\xC2-\xDF][\x80-\xBF] # double-byte sequences 110xxxxx 10xxxxxx 105 | \xE0[\xA0-\xBF][\x80-\xBF] # triple-byte sequences 1110xxxx 10xxxxxx * 2 106 | [\xE1-\xEC][\x80-\xBF]{2} 107 | \xED[\x80-\x9F][\x80-\xBF] 108 | [\xEE-\xEF][\x80-\xBF]{2} 109 | \xF0[\x90-\xBF][\x80-\xBF]{2} # four-byte sequences 11110xxx 10xxxxxx * 3 110 | [\xF1-\xF3][\x80-\xBF]{3} 111 | \xF4[\x80-\x8F][\x80-\xBF]{2} 112 )/x'; 113 114 // Start with 1 element instead of 0 since the first thing we do is pop. 115 $chars = array( '' ); 116 do { 117 // We had some string left over from the last round, but we counted it in that last round. 118 array_pop( $chars ); 119 120 /* 121 * Split by UTF-8 character, limit to 1000 characters (last array element will contain 122 * the rest of the string). 123 */ 124 $pieces = preg_split( $regex, $str, 1000, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY ); 125 126 $chars = array_merge( $chars, $pieces ); 127 128 // If there's anything left over, repeat the loop. 129 } while ( count( $pieces ) > 1 && $str = array_pop( $pieces ) ); 130 131 return join( '', array_slice( $chars, $start, $length ) ); 132 } 133 134 if ( ! function_exists( 'mb_strlen' ) ) : 135 /** 136 * Compat function to mimic mb_strlen(). 137 * 138 * @ignore 139 * @since 4.2.0 140 * 141 * @see _mb_strlen() 142 * 143 * @param string $str The string to retrieve the character length from. 144 * @param string|null $encoding Optional. Character encoding to use. Default null. 145 * @return int String length of `$str`. 146 */ 147 function mb_strlen( $str, $encoding = null ) { 148 return _mb_strlen( $str, $encoding ); 149 } 150 endif; 151 152 /** 153 * Internal compat function to mimic mb_strlen(). 154 * 155 * Only understands UTF-8 and 8bit. All other character sets will be treated as 8bit. 156 * For $encoding === UTF-8, the `$str` input is expected to be a valid UTF-8 byte 157 * sequence. The behavior of this function for invalid inputs is undefined. 158 * 159 * @ignore 160 * @since 4.2.0 161 * 162 * @param string $str The string to retrieve the character length from. 163 * @param string|null $encoding Optional. Character encoding to use. Default null. 164 * @return int String length of `$str`. 165 */ 166 function _mb_strlen( $str, $encoding = null ) { 167 if ( null === $encoding ) { 168 $encoding = get_option( 'blog_charset' ); 169 } 170 171 /* 172 * The solution below works only for UTF-8, so in case of a different charset 173 * just use built-in strlen(). 174 */ 175 if ( ! in_array( $encoding, array( 'utf8', 'utf-8', 'UTF8', 'UTF-8' ) ) ) { 176 return strlen( $str ); 177 } 178 179 if ( _wp_can_use_pcre_u() ) { 180 // Use the regex unicode support to separate the UTF-8 characters into an array. 181 preg_match_all( '/./us', $str, $match ); 182 return count( $match[0] ); 183 } 184 185 $regex = '/(?: 186 [\x00-\x7F] # single-byte sequences 0xxxxxxx 187 | [\xC2-\xDF][\x80-\xBF] # double-byte sequences 110xxxxx 10xxxxxx 188 | \xE0[\xA0-\xBF][\x80-\xBF] # triple-byte sequences 1110xxxx 10xxxxxx * 2 189 | [\xE1-\xEC][\x80-\xBF]{2} 190 | \xED[\x80-\x9F][\x80-\xBF] 191 | [\xEE-\xEF][\x80-\xBF]{2} 192 | \xF0[\x90-\xBF][\x80-\xBF]{2} # four-byte sequences 11110xxx 10xxxxxx * 3 193 | [\xF1-\xF3][\x80-\xBF]{3} 194 | \xF4[\x80-\x8F][\x80-\xBF]{2} 195 )/x'; 196 197 // Start at 1 instead of 0 since the first thing we do is decrement. 198 $count = 1; 199 do { 200 // We had some string left over from the last round, but we counted it in that last round. 201 $count--; 202 203 /* 204 * Split by UTF-8 character, limit to 1000 characters (last array element will contain 205 * the rest of the string). 206 */ 207 $pieces = preg_split( $regex, $str, 1000 ); 208 209 // Increment. 210 $count += count( $pieces ); 211 212 // If there's anything left over, repeat the loop. 213 } while ( $str = array_pop( $pieces ) ); 214 215 // Fencepost: preg_split() always returns one extra item in the array. 216 return --$count; 217 } 218 219 if ( !function_exists('hash_hmac') ): 220 /** 221 * Compat function to mimic hash_hmac(). 222 * 223 * @ignore 224 * @since 3.2.0 225 * 226 * @see _hash_hmac() 227 * 228 * @param string $algo Hash algorithm. Accepts 'md5' or 'sha1'. 229 * @param string $data Data to be hashed. 230 * @param string $key Secret key to use for generating the hash. 231 * @param bool $raw_output Optional. Whether to output raw binary data (true), 232 * or lowercase hexits (false). Default false. 233 * @return string|false The hash in output determined by `$raw_output`. False if `$algo` 234 * is unknown or invalid. 235 */ 236 function hash_hmac($algo, $data, $key, $raw_output = false) { 237 return _hash_hmac($algo, $data, $key, $raw_output); 238 } 239 endif; 240 241 /** 242 * Internal compat function to mimic hash_hmac(). 243 * 244 * @ignore 245 * @since 3.2.0 246 * 247 * @param string $algo Hash algorithm. Accepts 'md5' or 'sha1'. 248 * @param string $data Data to be hashed. 249 * @param string $key Secret key to use for generating the hash. 250 * @param bool $raw_output Optional. Whether to output raw binary data (true), 251 * or lowercase hexits (false). Default false. 252 * @return string|false The hash in output determined by `$raw_output`. False if `$algo` 253 * is unknown or invalid. 254 */ 255 function _hash_hmac($algo, $data, $key, $raw_output = false) { 256 $packs = array('md5' => 'H32', 'sha1' => 'H40'); 257 258 if ( !isset($packs[$algo]) ) 259 return false; 260 261 $pack = $packs[$algo]; 262 263 if (strlen($key) > 64) 264 $key = pack($pack, $algo($key)); 265 266 $key = str_pad($key, 64, chr(0)); 267 268 $ipad = (substr($key, 0, 64) ^ str_repeat(chr(0x36), 64)); 269 $opad = (substr($key, 0, 64) ^ str_repeat(chr(0x5C), 64)); 270 271 $hmac = $algo($opad . pack($pack, $algo($ipad . $data))); 272 273 if ( $raw_output ) 274 return pack( $pack, $hmac ); 275 return $hmac; 276 } 277 278 if ( !function_exists('json_encode') ) { 279 function json_encode( $string ) { 280 global $wp_json; 281 282 if ( ! ( $wp_json instanceof Services_JSON ) ) { 283 require_once( ABSPATH . WPINC . '/class-json.php' ); 284 $wp_json = new Services_JSON(); 285 } 286 287 return $wp_json->encodeUnsafe( $string ); 288 } 289 } 290 291 if ( !function_exists('json_decode') ) { 292 /** 293 * @global Services_JSON $wp_json 294 * @param string $string 295 * @param bool $assoc_array 296 * @return object|array 297 */ 298 function json_decode( $string, $assoc_array = false ) { 299 global $wp_json; 300 301 if ( ! ($wp_json instanceof Services_JSON ) ) { 302 require_once( ABSPATH . WPINC . '/class-json.php' ); 303 $wp_json = new Services_JSON(); 304 } 305 306 $res = $wp_json->decode( $string ); 307 if ( $assoc_array ) 308 $res = _json_decode_object_helper( $res ); 309 return $res; 310 } 311 312 /** 313 * @param object $data 314 * @return array 315 */ 316 function _json_decode_object_helper($data) { 317 if ( is_object($data) ) 318 $data = get_object_vars($data); 319 return is_array($data) ? array_map(__FUNCTION__, $data) : $data; 320 } 321 } 322 -
new file src/wp-includes/compat/php-5.2.php
diff --git src/wp-includes/compat/php-5.2.php src/wp-includes/compat/php-5.2.php new file mode 100644 index 0000000000..25b740fddf
- + 1 <?php 2 /** 3 * Compatibility file for PHP 5.2 or older. 4 * 5 * @package compat 6 */ 7 8 if ( ! function_exists( 'array_replace_recursive' ) ) : 9 /** 10 * PHP-agnostic version of {@link array_replace_recursive()}. 11 * 12 * The array_replace_recursive() function is a PHP 5.3 function. WordPress 13 * currently supports down to PHP 5.2, so this method is a workaround 14 * for PHP 5.2. 15 * 16 * Note: array_replace_recursive() supports infinite arguments, but for our use- 17 * case, we only need to support two arguments. 18 * 19 * Subject to removal once WordPress makes PHP 5.3.0 the minimum requirement. 20 * 21 * @since 4.5.3 22 * 23 * @see https://secure.php.net/manual/en/function.array-replace-recursive.php#109390 24 * 25 * @param array $base Array with keys needing to be replaced. 26 * @param array $replacements Array with the replaced keys. 27 * 28 * @return array 29 */ 30 function array_replace_recursive( $base = array(), $replacements = array() ) { 31 foreach ( array_slice( func_get_args(), 1 ) as $replacements ) { 32 $bref_stack = array( &$base ); 33 $head_stack = array( $replacements ); 34 35 do { 36 end( $bref_stack ); 37 38 $bref = &$bref_stack[ key( $bref_stack ) ]; 39 $head = array_pop( $head_stack ); 40 41 unset( $bref_stack[ key( $bref_stack ) ] ); 42 43 foreach ( array_keys( $head ) as $key ) { 44 if ( isset( $key, $bref ) && 45 isset( $bref[ $key ] ) && is_array( $bref[ $key ] ) && 46 isset( $head[ $key ] ) && is_array( $head[ $key ] ) 47 ) { 48 $bref_stack[] = &$bref[ $key ]; 49 $head_stack[] = $head[ $key ]; 50 } else { 51 $bref[ $key ] = $head[ $key ]; 52 } 53 } 54 } while ( count( $head_stack ) ); 55 } 56 57 return $base; 58 } 59 endif; 60 61 /** 62 * Polyfill for the SPL autoloader. In PHP 5.2 (but not 5.3 and later), SPL can 63 * be disabled, and PHP 7.2 raises notices if the compiler finds an __autoload() 64 * function declaration. Function availability is checked here, and the 65 * autoloader is included only if necessary. 66 */ 67 if ( ! function_exists( 'spl_autoload_register' ) ) { 68 require_once ABSPATH . WPINC . '/compat/spl-autoload-compat.php'; 69 } -
new file src/wp-includes/compat/php-5.3.php
diff --git src/wp-includes/compat/php-5.3.php src/wp-includes/compat/php-5.3.php new file mode 100644 index 0000000000..afd0f18993
- + 1 <?php 2 3 // JSON_PRETTY_PRINT was introduced in PHP 5.4 4 // Defined here to prevent a notice when using it with wp_json_encode() 5 if ( ! defined( 'JSON_PRETTY_PRINT' ) ) { 6 define( 'JSON_PRETTY_PRINT', 128 ); 7 } 8 9 if ( ! interface_exists( 'JsonSerializable' ) ) { 10 define( 'WP_JSON_SERIALIZE_COMPATIBLE', true ); 11 /** 12 * JsonSerializable interface. 13 * 14 * Compatibility shim for PHP <5.4 15 * 16 * @link https://secure.php.net/jsonserializable 17 * 18 * @since 4.4.0 19 */ 20 interface JsonSerializable { 21 public function jsonSerialize(); 22 } 23 } -
new file src/wp-includes/compat/php-5.4.php
diff --git src/wp-includes/compat/php-5.4.php src/wp-includes/compat/php-5.4.php new file mode 100644 index 0000000000..da02d52818
- + 1 <?php 2 3 if ( ! function_exists( 'json_last_error_msg' ) ) : 4 /** 5 * Retrieves the error string of the last json_encode() or json_decode() call. 6 * 7 * @since 4.4.0 8 * 9 * @internal This is a compatibility function for PHP <5.5 10 * 11 * @return bool|string Returns the error message on success, "No Error" if no error has occurred, 12 * or false on failure. 13 */ 14 function json_last_error_msg() { 15 // See https://core.trac.wordpress.org/ticket/27799. 16 if ( ! function_exists( 'json_last_error' ) ) { 17 return false; 18 } 19 20 $last_error_code = json_last_error(); 21 22 // Just in case JSON_ERROR_NONE is not defined. 23 $error_code_none = defined( 'JSON_ERROR_NONE' ) ? JSON_ERROR_NONE : 0; 24 25 switch ( true ) { 26 case $last_error_code === $error_code_none: 27 return 'No error'; 28 29 case defined( 'JSON_ERROR_DEPTH' ) && JSON_ERROR_DEPTH === $last_error_code: 30 return 'Maximum stack depth exceeded'; 31 32 case defined( 'JSON_ERROR_STATE_MISMATCH' ) && JSON_ERROR_STATE_MISMATCH === $last_error_code: 33 return 'State mismatch (invalid or malformed JSON)'; 34 35 case defined( 'JSON_ERROR_CTRL_CHAR' ) && JSON_ERROR_CTRL_CHAR === $last_error_code: 36 return 'Control character error, possibly incorrectly encoded'; 37 38 case defined( 'JSON_ERROR_SYNTAX' ) && JSON_ERROR_SYNTAX === $last_error_code: 39 return 'Syntax error'; 40 41 case defined( 'JSON_ERROR_UTF8' ) && JSON_ERROR_UTF8 === $last_error_code: 42 return 'Malformed UTF-8 characters, possibly incorrectly encoded'; 43 44 case defined( 'JSON_ERROR_RECURSION' ) && JSON_ERROR_RECURSION === $last_error_code: 45 return 'Recursion detected'; 46 47 case defined( 'JSON_ERROR_INF_OR_NAN' ) && JSON_ERROR_INF_OR_NAN === $last_error_code: 48 return 'Inf and NaN cannot be JSON encoded'; 49 50 case defined( 'JSON_ERROR_UNSUPPORTED_TYPE' ) && JSON_ERROR_UNSUPPORTED_TYPE === $last_error_code: 51 return 'Type is not supported'; 52 53 default: 54 return 'An unknown error occurred'; 55 } 56 } 57 endif; -
new file src/wp-includes/compat/php-5.5.php
diff --git src/wp-includes/compat/php-5.5.php src/wp-includes/compat/php-5.5.php new file mode 100644 index 0000000000..5563b92248
- + 1 <?php 2 3 if ( ! function_exists( 'hash_equals' ) ) : 4 /** 5 * Timing attack safe string comparison 6 * 7 * Compares two strings using the same time whether they're equal or not. 8 * 9 * This function was added in PHP 5.6. 10 * 11 * Note: It can leak the length of a string when arguments of differing length are supplied. 12 * 13 * @since 3.9.2 14 * 15 * @param string $a Expected string. 16 * @param string $b Actual, user supplied, string. 17 * @return bool Whether strings are equal. 18 */ 19 function hash_equals( $a, $b ) { 20 $a_length = strlen( $a ); 21 if ( $a_length !== strlen( $b ) ) { 22 return false; 23 } 24 $result = 0; 25 26 // Do not attempt to "optimize" this. 27 for ( $i = 0; $i < $a_length; $i++ ) { 28 $result |= ord( $a[ $i ] ) ^ ord( $b[ $i ] ); 29 } 30 31 return $result === 0; 32 } 33 endif; -
new file src/wp-includes/compat/php-5.6.php
diff --git src/wp-includes/compat/php-5.6.php src/wp-includes/compat/php-5.6.php new file mode 100644 index 0000000000..a5c4c7bb69
- + 1 <?php 2 3 // random_int was introduced in PHP 7.0 4 if ( ! function_exists( 'random_int' ) ) { 5 require ABSPATH . WPINC . '/random_compat/random.php'; 6 } -
new file src/wp-includes/compat/php-7.0.php
diff --git src/wp-includes/compat/php-7.0.php src/wp-includes/compat/php-7.0.php new file mode 100644 index 0000000000..b3d9bbc7f3
- + 1 <?php -
new file src/wp-includes/compat/php-7.1.php
diff --git src/wp-includes/compat/php-7.1.php src/wp-includes/compat/php-7.1.php new file mode 100644 index 0000000000..b3d9bbc7f3
- + 1 <?php -
new file src/wp-includes/compat/php-7.2.php
diff --git src/wp-includes/compat/php-7.2.php src/wp-includes/compat/php-7.2.php new file mode 100644 index 0000000000..b3d9bbc7f3
- + 1 <?php