wp/wp-includes/compat.php
changeset 9 177826044cd9
parent 7 cf61fcea0001
child 16 a86126ab1dd4
equal deleted inserted replaced
8:c7c34916027a 9:177826044cd9
     5  * @package PHP
     5  * @package PHP
     6  * @access private
     6  * @access private
     7  */
     7  */
     8 
     8 
     9 // If gettext isn't available
     9 // If gettext isn't available
    10 if ( !function_exists('_') ) {
    10 if ( ! function_exists( '_' ) ) {
    11 	function _($string) {
    11 	function _( $string ) {
    12 		return $string;
    12 		return $string;
    13 	}
    13 	}
    14 }
    14 }
    15 
    15 
    16 /**
    16 /**
   123 		 */
   123 		 */
   124 		$pieces = preg_split( $regex, $str, 1000, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY );
   124 		$pieces = preg_split( $regex, $str, 1000, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY );
   125 
   125 
   126 		$chars = array_merge( $chars, $pieces );
   126 		$chars = array_merge( $chars, $pieces );
   127 
   127 
   128 	// If there's anything left over, repeat the loop.
   128 		// If there's anything left over, repeat the loop.
   129 	} while ( count( $pieces ) > 1 && $str = array_pop( $pieces ) );
   129 	} while ( count( $pieces ) > 1 && $str = array_pop( $pieces ) );
   130 
   130 
   131 	return join( '', array_slice( $chars, $start, $length ) );
   131 	return join( '', array_slice( $chars, $start, $length ) );
   132 }
   132 }
   133 
   133 
   207 		$pieces = preg_split( $regex, $str, 1000 );
   207 		$pieces = preg_split( $regex, $str, 1000 );
   208 
   208 
   209 		// Increment.
   209 		// Increment.
   210 		$count += count( $pieces );
   210 		$count += count( $pieces );
   211 
   211 
   212 	// If there's anything left over, repeat the loop.
   212 		// If there's anything left over, repeat the loop.
   213 	} while ( $str = array_pop( $pieces ) );
   213 	} while ( $str = array_pop( $pieces ) );
   214 
   214 
   215 	// Fencepost: preg_split() always returns one extra item in the array.
   215 	// Fencepost: preg_split() always returns one extra item in the array.
   216 	return --$count;
   216 	return --$count;
   217 }
   217 }
   218 
   218 
   219 if ( !function_exists('hash_hmac') ):
   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 
   220 /**
   241 /**
   221  * Compat function to mimic hash_hmac().
   242  * Internal compat function to mimic hash_hmac().
   222  *
   243  *
   223  * @ignore
   244  * @ignore
   224  * @since 3.2.0
   245  * @since 3.2.0
   225  *
       
   226  * @see _hash_hmac()
       
   227  *
   246  *
   228  * @param string $algo       Hash algorithm. Accepts 'md5' or 'sha1'.
   247  * @param string $algo       Hash algorithm. Accepts 'md5' or 'sha1'.
   229  * @param string $data       Data to be hashed.
   248  * @param string $data       Data to be hashed.
   230  * @param string $key        Secret key to use for generating the hash.
   249  * @param string $key        Secret key to use for generating the hash.
   231  * @param bool   $raw_output Optional. Whether to output raw binary data (true),
   250  * @param bool   $raw_output Optional. Whether to output raw binary data (true),
   232  *                           or lowercase hexits (false). Default false.
   251  *                           or lowercase hexits (false). Default false.
   233  * @return string|false The hash in output determined by `$raw_output`. False if `$algo`
   252  * @return string|false The hash in output determined by `$raw_output`. False if `$algo`
   234  *                      is unknown or invalid.
   253  *                      is unknown or invalid.
   235  */
   254  */
   236 function hash_hmac($algo, $data, $key, $raw_output = false) {
   255 function _hash_hmac( $algo, $data, $key, $raw_output = false ) {
   237 	return _hash_hmac($algo, $data, $key, $raw_output);
   256 	$packs = array(
   238 }
   257 		'md5'  => 'H32',
   239 endif;
   258 		'sha1' => 'H40',
   240 
   259 	);
   241 /**
   260 
   242  * Internal compat function to mimic hash_hmac().
   261 	if ( ! isset( $packs[ $algo ] ) ) {
   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;
   262 		return false;
   260 
   263 	}
   261 	$pack = $packs[$algo];
   264 
   262 
   265 	$pack = $packs[ $algo ];
   263 	if (strlen($key) > 64)
   266 
   264 		$key = pack($pack, $algo($key));
   267 	if ( strlen( $key ) > 64 ) {
   265 
   268 		$key = pack( $pack, $algo( $key ) );
   266 	$key = str_pad($key, 64, chr(0));
   269 	}
   267 
   270 
   268 	$ipad = (substr($key, 0, 64) ^ str_repeat(chr(0x36), 64));
   271 	$key = str_pad( $key, 64, chr( 0 ) );
   269 	$opad = (substr($key, 0, 64) ^ str_repeat(chr(0x5C), 64));
   272 
   270 
   273 	$ipad = ( substr( $key, 0, 64 ) ^ str_repeat( chr( 0x36 ), 64 ) );
   271 	$hmac = $algo($opad . pack($pack, $algo($ipad . $data)));
   274 	$opad = ( substr( $key, 0, 64 ) ^ str_repeat( chr( 0x5C ), 64 ) );
   272 
   275 
   273 	if ( $raw_output )
   276 	$hmac = $algo( $opad . pack( $pack, $algo( $ipad . $data ) ) );
       
   277 
       
   278 	if ( $raw_output ) {
   274 		return pack( $pack, $hmac );
   279 		return pack( $pack, $hmac );
       
   280 	}
   275 	return $hmac;
   281 	return $hmac;
   276 }
   282 }
   277 
   283 
   278 if ( !function_exists('json_encode') ) {
   284 if ( ! function_exists( 'json_encode' ) ) {
   279 	function json_encode( $string ) {
   285 	function json_encode( $string ) {
   280 		global $wp_json;
   286 		global $wp_json;
   281 
   287 
   282 		if ( ! ( $wp_json instanceof Services_JSON ) ) {
   288 		if ( ! ( $wp_json instanceof Services_JSON ) ) {
   283 			require_once( ABSPATH . WPINC . '/class-json.php' );
   289 			require_once( ABSPATH . WPINC . '/class-json.php' );
   286 
   292 
   287 		return $wp_json->encodeUnsafe( $string );
   293 		return $wp_json->encodeUnsafe( $string );
   288 	}
   294 	}
   289 }
   295 }
   290 
   296 
   291 if ( !function_exists('json_decode') ) {
   297 if ( ! function_exists( 'json_decode' ) ) {
   292 	/**
   298 	/**
   293 	 * @global Services_JSON $wp_json
   299 	 * @global Services_JSON $wp_json
   294 	 * @param string $string
   300 	 * @param string $string
   295 	 * @param bool   $assoc_array
   301 	 * @param bool   $assoc_array
   296 	 * @return object|array
   302 	 * @return object|array
   297 	 */
   303 	 */
   298 	function json_decode( $string, $assoc_array = false ) {
   304 	function json_decode( $string, $assoc_array = false ) {
   299 		global $wp_json;
   305 		global $wp_json;
   300 
   306 
   301 		if ( ! ($wp_json instanceof Services_JSON ) ) {
   307 		if ( ! ( $wp_json instanceof Services_JSON ) ) {
   302 			require_once( ABSPATH . WPINC . '/class-json.php' );
   308 			require_once( ABSPATH . WPINC . '/class-json.php' );
   303 			$wp_json = new Services_JSON();
   309 			$wp_json = new Services_JSON();
   304 		}
   310 		}
   305 
   311 
   306 		$res = $wp_json->decode( $string );
   312 		$res = $wp_json->decode( $string );
   307 		if ( $assoc_array )
   313 		if ( $assoc_array ) {
   308 			$res = _json_decode_object_helper( $res );
   314 			$res = _json_decode_object_helper( $res );
       
   315 		}
   309 		return $res;
   316 		return $res;
   310 	}
   317 	}
   311 
   318 
   312 	/**
   319 	/**
   313 	 * @param object $data
   320 	 * @param object $data
   314 	 * @return array
   321 	 * @return array
   315 	 */
   322 	 */
   316 	function _json_decode_object_helper($data) {
   323 	function _json_decode_object_helper( $data ) {
   317 		if ( is_object($data) )
   324 		if ( is_object( $data ) ) {
   318 			$data = get_object_vars($data);
   325 			$data = get_object_vars( $data );
   319 		return is_array($data) ? array_map(__FUNCTION__, $data) : $data;
   326 		}
       
   327 		return is_array( $data ) ? array_map( __FUNCTION__, $data ) : $data;
   320 	}
   328 	}
   321 }
   329 }
   322 
   330 
   323 if ( ! function_exists( 'hash_equals' ) ) :
   331 if ( ! function_exists( 'hash_equals' ) ) :
   324 /**
   332 	/**
   325  * Timing attack safe string comparison
   333 	 * Timing attack safe string comparison
   326  *
   334 	 *
   327  * Compares two strings using the same time whether they're equal or not.
   335 	 * Compares two strings using the same time whether they're equal or not.
   328  *
   336 	 *
   329  * This function was added in PHP 5.6.
   337 	 * This function was added in PHP 5.6.
   330  *
   338 	 *
   331  * Note: It can leak the length of a string when arguments of differing length are supplied.
   339 	 * Note: It can leak the length of a string when arguments of differing length are supplied.
   332  *
   340 	 *
   333  * @since 3.9.2
   341 	 * @since 3.9.2
   334  *
   342 	 *
   335  * @param string $a Expected string.
   343 	 * @param string $a Expected string.
   336  * @param string $b Actual, user supplied, string.
   344 	 * @param string $b Actual, user supplied, string.
   337  * @return bool Whether strings are equal.
   345 	 * @return bool Whether strings are equal.
   338  */
   346 	 */
   339 function hash_equals( $a, $b ) {
   347 	function hash_equals( $a, $b ) {
   340 	$a_length = strlen( $a );
   348 		$a_length = strlen( $a );
   341 	if ( $a_length !== strlen( $b ) ) {
   349 		if ( $a_length !== strlen( $b ) ) {
   342 		return false;
   350 			return false;
   343 	}
   351 		}
   344 	$result = 0;
   352 		$result = 0;
   345 
   353 
   346 	// Do not attempt to "optimize" this.
   354 		// Do not attempt to "optimize" this.
   347 	for ( $i = 0; $i < $a_length; $i++ ) {
   355 		for ( $i = 0; $i < $a_length; $i++ ) {
   348 		$result |= ord( $a[ $i ] ) ^ ord( $b[ $i ] );
   356 			$result |= ord( $a[ $i ] ) ^ ord( $b[ $i ] );
   349 	}
   357 		}
   350 
   358 
   351 	return $result === 0;
   359 		return $result === 0;
   352 }
   360 	}
   353 endif;
   361 endif;
   354 
   362 
   355 // JSON_PRETTY_PRINT was introduced in PHP 5.4
   363 // JSON_PRETTY_PRINT was introduced in PHP 5.4
   356 // Defined here to prevent a notice when using it with wp_json_encode()
   364 // Defined here to prevent a notice when using it with wp_json_encode()
   357 if ( ! defined( 'JSON_PRETTY_PRINT' ) ) {
   365 if ( ! defined( 'JSON_PRETTY_PRINT' ) ) {
   432 
   440 
   433 // random_int was introduced in PHP 7.0
   441 // random_int was introduced in PHP 7.0
   434 if ( ! function_exists( 'random_int' ) ) {
   442 if ( ! function_exists( 'random_int' ) ) {
   435 	require ABSPATH . WPINC . '/random_compat/random.php';
   443 	require ABSPATH . WPINC . '/random_compat/random.php';
   436 }
   444 }
       
   445 // sodium_crypto_box was introduced in PHP 7.2
       
   446 if ( ! function_exists( 'sodium_crypto_box' ) ) {
       
   447 	require ABSPATH . WPINC . '/sodium_compat/autoload.php';
       
   448 }
   437 
   449 
   438 if ( ! function_exists( 'array_replace_recursive' ) ) :
   450 if ( ! function_exists( 'array_replace_recursive' ) ) :
   439 	/**
   451 	/**
   440 	 * PHP-agnostic version of {@link array_replace_recursive()}.
   452 	 * PHP-agnostic version of {@link array_replace_recursive()}.
   441 	 *
   453 	 *
   470 
   482 
   471 				unset( $bref_stack[ key( $bref_stack ) ] );
   483 				unset( $bref_stack[ key( $bref_stack ) ] );
   472 
   484 
   473 				foreach ( array_keys( $head ) as $key ) {
   485 				foreach ( array_keys( $head ) as $key ) {
   474 					if ( isset( $key, $bref ) &&
   486 					if ( isset( $key, $bref ) &&
   475 					     isset( $bref[ $key ] ) && is_array( $bref[ $key ] ) &&
   487 						isset( $bref[ $key ] ) && is_array( $bref[ $key ] ) &&
   476 					     isset( $head[ $key ] ) && is_array( $head[ $key ] )
   488 						isset( $head[ $key ] ) && is_array( $head[ $key ] ) ) {
   477 					) {
   489 
   478 						$bref_stack[] = &$bref[ $key ];
   490 						$bref_stack[] = &$bref[ $key ];
   479 						$head_stack[] = $head[ $key ];
   491 						$head_stack[] = $head[ $key ];
   480 					} else {
   492 					} else {
   481 						$bref[ $key ] = $head[ $key ];
   493 						$bref[ $key ] = $head[ $key ];
   482 					}
   494 					}