WordPress.org

Make WordPress Core

Ticket #34631: 34631.diff

File 34631.diff, 7.3 KB (added by Cybr, 6 years ago)
  • wp-includes/compat.php

     
    216216        return --$count;
    217217}
    218218
     219if ( ! function_exists( 'mb_strpos' ) ) :
     220        /**
     221         * Compat function to mimic mb_strpos().
     222         *
     223         * @ignore
     224         * @since 4.5.0
     225         *
     226         * @see _mb_strpos()
     227         *
     228         * @param string                $haystack       The string to search in.
     229         * @param mixed                 $needle         If needle is not a string, it is converted to an integer and applied as the ordinal value of a character.
     230         * @param int                   $offset         Optional, search will start this number of characters counted from the beginning of the string. The offset cannot be negative.
     231         * @param string|null $encoding Optional. Character encoding to use. Default null.
     232         * @return int Position of first occurence found of $haystack of `$needle`.
     233         */
     234        function mb_strpos( $haystack, $needle, $offset = 0, $encoding = null ) {
     235                return _mb_strpos( $haystack, $needle, $offset, $encoding );
     236        }
     237endif;
     238
     239/**
     240 * Internal compat function to mimic mb_strpos().
     241 *
     242 * Only understands UTF-8 and 8bit.  All other character sets will be treated as 8bit.
     243 * For $encoding === UTF-8, the $str input is expected to be a valid UTF-8 byte sequence.
     244 * The behavior of this function for invalid inputs is PHP compliant.
     245 *
     246 * @ignore
     247 * @since 4.5.0
     248 *
     249 * @param string                $haystack       The string to search in.
     250 * @param mixed                 $needle         If needle is not a string, it is converted to an integer and applied as the ordinal value of a character.
     251 * @param int                   $offset         Optional, search will start this number of characters counted from the beginning of the string. The offset cannot be negative.
     252 * @param string|null   $encoding       Optional. Character encoding to use. Default null.
     253 *
     254 * @return int Position of first occurence found of $haystack of `$needle`.
     255 */
     256function _mb_strpos( $haystack, $needle, $offset = 0, $encoding = null ) {
     257
     258        if ( null === $encoding ) {
     259                $encoding = get_option( 'blog_charset' );
     260        }
     261
     262        // The solution below works only for UTF-8,
     263        // So in case of a different charset just use built-in strpos()
     264        if ( ! in_array( $encoding, array( 'utf8', 'utf-8', 'UTF8', 'UTF-8' ) ) ) {
     265                return $offset === 0 ? strpos( $haystack, $needle ) : strpos( $haystack, $needle, $offset );
     266        }
     267
     268        $haystack_len = mb_strlen( $haystack );
     269
     270        if ( $offset < (int) 0 || $offset > $haystack_len ) {
     271                trigger_error( 'mb_strpos(): Offset not contained in string', E_USER_WARNING );
     272                return false;
     273        }
     274
     275        if ( ! is_string( $needle ) ) {
     276                $needle = (int) $needle;
     277
     278                if ( ! is_int( $needle ) ) {
     279                        trigger_error( 'mb_strpos(): Array to string conversion', E_USER_WARNING );
     280                        return false;
     281                }
     282        }
     283
     284        if ( empty( $needle ) ) {
     285                trigger_error( 'mb_strpos(): Empty needle', E_USER_WARNING );
     286                return false;
     287        }
     288
     289        // Slice off the offset
     290        $haystack_sub = mb_substr( $haystack, $offset );
     291
     292        if ( _wp_can_use_pcre_u() ) {
     293                // Use the regex unicode support to separate the UTF-8 characters into an array
     294                preg_match_all( "/./us", $haystack, $match_h );
     295                preg_match_all( "/$needle/us", $haystack_sub, $match_n );
     296
     297                $inter = array_intersect( $match_h[0], $match_n[0] );
     298
     299                if ( ! isset( $inter ) )
     300                        return false;
     301
     302                //* Prevent bugs, (re)assign var.
     303                $pos = null;
     304
     305                // Find first occurence greater than or equal to offset
     306                foreach ( $inter as $key => $value ) {
     307                        if ( $key >= $offset ) {
     308                                $pos = $key;
     309                                break;
     310                        }
     311                }
     312
     313                //* No key has been found.
     314                if ( ! isset( $pos ) )
     315                        return false;
     316
     317                return (int) $pos;
     318        }
     319
     320        $regex = '/(
     321                  [\x00-\x7F]                  # single-byte sequences   0xxxxxxx
     322                | [\xC2-\xDF][\x80-\xBF]       # double-byte sequences   110xxxxx 10xxxxxx
     323                | \xE0[\xA0-\xBF][\x80-\xBF]   # triple-byte sequences   1110xxxx 10xxxxxx * 2
     324                | [\xE1-\xEC][\x80-\xBF]{2}
     325                | \xED[\x80-\x9F][\x80-\xBF]
     326                | [\xEE-\xEF][\x80-\xBF]{2}
     327                | \xF0[\x90-\xBF][\x80-\xBF]{2} # four-byte sequences   11110xxx 10xxxxxx * 3
     328                | [\xF1-\xF3][\x80-\xBF]{3}
     329                | \xF4[\x80-\x8F][\x80-\xBF]{2}
     330        )/x';
     331
     332        /**
     333         * Place haystack into array
     334         */
     335        $match_h = array( '' ); // Start with 1 element instead of 0 since the first thing we do is pop
     336        do {
     337                // We had some string left over from the last round, but we counted it in that last round.
     338                array_pop( $match_h );
     339
     340                // Split by UTF-8 character, limit to 1000 characters (last array element will contain the rest of the string)
     341                $pieces = preg_split( $regex, $haystack, 1000, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY );
     342
     343                $match_h = array_merge( $match_h, $pieces );
     344        } while ( count( $pieces ) > 1 && $haystack = array_pop( $pieces ) ); // If there's anything left over, repeat the loop.
     345
     346        /**
     347         * Place haystack offset into array
     348         */
     349        $match_hs = array( '' ); // Start with 1 element instead of 0 since the first thing we do is pop
     350        do {
     351                // We had some string left over from the last round, but we counted it in that last round.
     352                array_pop( $match_hs );
     353
     354                // Split by UTF-8 character, limit to 1000 characters (last array element will contain the rest of the string)
     355                $pieces = preg_split( $regex, $haystack_sub, 1000, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY );
     356
     357                $match_hs = array_merge( $match_hs, $pieces );
     358        } while ( count( $pieces ) > 1 && $haystack_sub = array_pop( $pieces ) ); // If there's anything left over, repeat the loop.
     359
     360        /**
     361         * Put needle into array
     362         */
     363        $match_n = array( '' ); // Start with 1 element instead of 0 since the first thing we do is pop
     364        do {
     365                // We had some string left over from the last round, but we counted it in that last round.
     366                array_pop( $match_n );
     367
     368                // Split by UTF-8 character, limit to 1000 characters (last array element will contain the rest of the string)
     369                $pieces = preg_split( $regex, $needle, 1000, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY );
     370
     371                $match_n = array_merge( $match_n, $pieces );
     372        } while ( count( $pieces ) > 1 && $needle = array_pop( $pieces ) ); // If there's anything left over, repeat the loop.
     373
     374        /**
     375         * Compute match of haystack offset with needle
     376         * If passed, return the array key number within the full haystack.
     377         */
     378        if ( false !== in_array( $match_n[0], $match_hs ) ) {
     379                $inter = array_intersect( $match_h, $match_n );
     380
     381                if ( ! isset( $inter ) )
     382                        return false;
     383
     384                //* Prevent bugs, (re)assign var.
     385                $pos = null;
     386
     387                // Find first occurence greater than or equal to offset
     388                foreach ( $inter as $key => $value ) {
     389                        if ( $key >= $offset ) {
     390                                $pos = $key;
     391                                break;
     392                        }
     393                }
     394
     395                //* No key has been found.
     396                if ( ! isset( $pos ) )
     397                        return false;
     398
     399                return (int) $pos;
     400        } else {
     401                return false;
     402        }
     403}
     404
     405
     406/**
     407 * Internal compat function to mimic mb_strpos().
     408 *
     409 * Only understands UTF-8 and 8bit.  All other character sets will be treated as 8bit.
     410 * For $encoding === UTF-8, the `$str` input is expected to be a valid UTF-8 byte
     411 * sequence. The behavior of this function for invalid inputs is undefined.
     412 *
     413 * @ignore
     414 * @since 4.2.0
     415 *
     416 * @param string      $str      The string to retrieve the character length from.
     417 * @param string|null $encoding Optional. Character encoding to use. Default null.
     418 * @return int String length of `$str`.
     419 */
     420
    219421if ( !function_exists('hash_hmac') ):
    220422/**
    221423 * Compat function to mimic hash_hmac().