Index: wp-includes/compat.php
===================================================================
--- wp-includes/compat.php	(revision 36345)
+++ wp-includes/compat.php	(working copy)
@@ -216,6 +216,208 @@
 	return --$count;
 }
 
+if ( ! function_exists( 'mb_strpos' ) ) :
+	/**
+	 * Compat function to mimic mb_strpos().
+	 *
+	 * @ignore
+	 * @since 4.5.0
+	 *
+	 * @see _mb_strpos()
+	 *
+	 * @param string 		$haystack	The string to search in.
+	 * @param mixed 		$needle		If needle is not a string, it is converted to an integer and applied as the ordinal value of a character.
+	 * @param int			$offset		Optional, search will start this number of characters counted from the beginning of the string. The offset cannot be negative.
+	 * @param string|null $encoding	Optional. Character encoding to use. Default null.
+	 * @return int Position of first occurence found of $haystack of `$needle`.
+	 */
+	function mb_strpos( $haystack, $needle, $offset = 0, $encoding = null ) {
+		return _mb_strpos( $haystack, $needle, $offset, $encoding );
+	}
+endif;
+
+/**
+ * Internal compat function to mimic mb_strpos().
+ *
+ * Only understands UTF-8 and 8bit.  All other character sets will be treated as 8bit.
+ * For $encoding === UTF-8, the $str input is expected to be a valid UTF-8 byte sequence.
+ * The behavior of this function for invalid inputs is PHP compliant.
+ *
+ * @ignore
+ * @since 4.5.0
+ *
+ * @param string		$haystack	The string to search in.
+ * @param mixed 		$needle		If needle is not a string, it is converted to an integer and applied as the ordinal value of a character.
+ * @param int			$offset		Optional, search will start this number of characters counted from the beginning of the string. The offset cannot be negative.
+ * @param string|null	$encoding	Optional. Character encoding to use. Default null.
+ *
+ * @return int Position of first occurence found of $haystack of `$needle`.
+ */
+function _mb_strpos( $haystack, $needle, $offset = 0, $encoding = null ) {
+
+	if ( null === $encoding ) {
+		$encoding = get_option( 'blog_charset' );
+	}
+
+	// The solution below works only for UTF-8,
+	// So in case of a different charset just use built-in strpos()
+	if ( ! in_array( $encoding, array( 'utf8', 'utf-8', 'UTF8', 'UTF-8' ) ) ) {
+		return $offset === 0 ? strpos( $haystack, $needle ) : strpos( $haystack, $needle, $offset );
+	}
+
+	$haystack_len = mb_strlen( $haystack );
+
+	if ( $offset < (int) 0 || $offset > $haystack_len ) {
+		trigger_error( 'mb_strpos(): Offset not contained in string', E_USER_WARNING );
+		return false;
+	}
+
+	if ( ! is_string( $needle ) ) {
+		$needle = (int) $needle;
+
+		if ( ! is_int( $needle ) ) {
+			trigger_error( 'mb_strpos(): Array to string conversion', E_USER_WARNING );
+			return false;
+		}
+	}
+
+	if ( empty( $needle ) ) {
+		trigger_error( 'mb_strpos(): Empty needle', E_USER_WARNING );
+		return false;
+	}
+
+	// Slice off the offset
+	$haystack_sub = mb_substr( $haystack, $offset );
+
+	if ( _wp_can_use_pcre_u() ) {
+		// Use the regex unicode support to separate the UTF-8 characters into an array
+		preg_match_all( "/./us", $haystack, $match_h );
+		preg_match_all( "/$needle/us", $haystack_sub, $match_n );
+
+		$inter = array_intersect( $match_h[0], $match_n[0] );
+
+		if ( ! isset( $inter ) )
+			return false;
+
+		//* Prevent bugs, (re)assign var.
+		$pos = null;
+
+		// Find first occurence greater than or equal to offset
+		foreach ( $inter as $key => $value ) {
+			if ( $key >= $offset ) {
+				$pos = $key;
+				break;
+			}
+		}
+
+		//* No key has been found.
+		if ( ! isset( $pos ) )
+			return false;
+
+		return (int) $pos;
+	}
+
+	$regex = '/(
+		  [\x00-\x7F]                  # single-byte sequences   0xxxxxxx
+		| [\xC2-\xDF][\x80-\xBF]       # double-byte sequences   110xxxxx 10xxxxxx
+		| \xE0[\xA0-\xBF][\x80-\xBF]   # triple-byte sequences   1110xxxx 10xxxxxx * 2
+		| [\xE1-\xEC][\x80-\xBF]{2}
+		| \xED[\x80-\x9F][\x80-\xBF]
+		| [\xEE-\xEF][\x80-\xBF]{2}
+		| \xF0[\x90-\xBF][\x80-\xBF]{2} # four-byte sequences   11110xxx 10xxxxxx * 3
+		| [\xF1-\xF3][\x80-\xBF]{3}
+		| \xF4[\x80-\x8F][\x80-\xBF]{2}
+	)/x';
+
+	/**
+	 * Place haystack into array
+	 */
+	$match_h = array( '' ); // Start with 1 element instead of 0 since the first thing we do is pop
+	do {
+		// We had some string left over from the last round, but we counted it in that last round.
+		array_pop( $match_h );
+
+		// Split by UTF-8 character, limit to 1000 characters (last array element will contain the rest of the string)
+		$pieces = preg_split( $regex, $haystack, 1000, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY );
+
+		$match_h = array_merge( $match_h, $pieces );
+	} while ( count( $pieces ) > 1 && $haystack = array_pop( $pieces ) ); // If there's anything left over, repeat the loop.
+
+	/**
+	 * Place haystack offset into array
+	 */
+	$match_hs = array( '' ); // Start with 1 element instead of 0 since the first thing we do is pop
+	do {
+		// We had some string left over from the last round, but we counted it in that last round.
+		array_pop( $match_hs );
+
+		// Split by UTF-8 character, limit to 1000 characters (last array element will contain the rest of the string)
+		$pieces = preg_split( $regex, $haystack_sub, 1000, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY );
+
+		$match_hs = array_merge( $match_hs, $pieces );
+	} while ( count( $pieces ) > 1 && $haystack_sub = array_pop( $pieces ) ); // If there's anything left over, repeat the loop.
+
+	/**
+	 * Put needle into array
+	 */
+	$match_n = array( '' ); // Start with 1 element instead of 0 since the first thing we do is pop
+	do {
+		// We had some string left over from the last round, but we counted it in that last round.
+		array_pop( $match_n );
+
+		// Split by UTF-8 character, limit to 1000 characters (last array element will contain the rest of the string)
+		$pieces = preg_split( $regex, $needle, 1000, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY );
+
+		$match_n = array_merge( $match_n, $pieces );
+	} while ( count( $pieces ) > 1 && $needle = array_pop( $pieces ) ); // If there's anything left over, repeat the loop.
+
+	/**
+	 * Compute match of haystack offset with needle
+	 * If passed, return the array key number within the full haystack.
+	 */
+	if ( false !== in_array( $match_n[0], $match_hs ) ) {
+		$inter = array_intersect( $match_h, $match_n );
+
+		if ( ! isset( $inter ) )
+			return false;
+
+		//* Prevent bugs, (re)assign var.
+		$pos = null;
+
+		// Find first occurence greater than or equal to offset
+		foreach ( $inter as $key => $value ) {
+			if ( $key >= $offset ) {
+				$pos = $key;
+				break;
+			}
+		}
+
+		//* No key has been found.
+		if ( ! isset( $pos ) )
+			return false;
+
+		return (int) $pos;
+	} else {
+		return false;
+	}
+}
+
+
+/**
+ * Internal compat function to mimic mb_strpos().
+ *
+ * Only understands UTF-8 and 8bit.  All other character sets will be treated as 8bit.
+ * For $encoding === UTF-8, the `$str` input is expected to be a valid UTF-8 byte
+ * sequence. The behavior of this function for invalid inputs is undefined.
+ *
+ * @ignore
+ * @since 4.2.0
+ *
+ * @param string      $str      The string to retrieve the character length from.
+ * @param string|null $encoding Optional. Character encoding to use. Default null.
+ * @return int String length of `$str`.
+ */
+
 if ( !function_exists('hash_hmac') ):
 /**
  * Compat function to mimic hash_hmac().
