Index: wp-includes/compat.php
===================================================================
--- wp-includes/compat.php	(revision 21088)
+++ wp-includes/compat.php	(working copy)
@@ -14,24 +14,41 @@
 }
 
 if ( !function_exists('mb_substr') ):
-	function mb_substr( $str, $start, $length=null, $encoding=null ) {
+	function mb_substr( $str, $start, $length = null, $encoding = null ) {
 		return _mb_substr($str, $start, $length, $encoding);
 	}
 endif;
 
-function _mb_substr( $str, $start, $length=null, $encoding=null ) {
-	// the solution below, works only for utf-8, so in case of a different
+function _mb_substr( $str, $start, $length = null, $encoding = null ) {
+	// the solution below works only for utf-8, so in case of a different
 	// charset, just use built-in substr
 	$charset = get_option( 'blog_charset' );
-	if ( !in_array( $charset, array('utf8', 'utf-8', 'UTF8', 'UTF-8') ) ) {
-		return is_null( $length )? substr( $str, $start ) : substr( $str, $start, $length);
+	if ( !in_array( $charset, array( 'utf8', 'utf-8', 'UTF8', 'UTF-8' ) ) ) {
+		return is_null( $length ) ? substr( $str, $start ) : substr( $str, $start, $length);
 	}
 	// use the regex unicode support to separate the UTF-8 characters into an array
 	preg_match_all( '/./us', $str, $match );
-	$chars = is_null( $length )? array_slice( $match[0], $start ) : array_slice( $match[0], $start, $length );
+	$chars = is_null( $length ) ? array_slice( $match[0], $start ) : array_slice( $match[0], $start, $length );
 	return implode( '', $chars );
 }
 
+if ( !function_exists('mb_strlen') ):
+	function mb_strlen( $str, $encoding = null ) {
+		return _mb_strlen($str, $encoding);
+	}
+endif;
+
+function _mb_strlen( $str, $encoding = null ) {
+	// the solution below works only for utf-8, so in case of a different
+	// charset, just use built-in strlen
+	$charset = get_option( 'blog_charset' );
+	if ( !in_array( $charset, array( 'utf8', 'utf-8', 'UTF8', 'UTF-8' ) ) ) {
+		return strlen( $str );
+	}
+	// use the regex unicode support to separate the UTF-8 characters into an array
+	return preg_match_all( '/./us', $str, $match );
+}
+
 if ( !function_exists('hash_hmac') ):
 function hash_hmac($algo, $data, $key, $raw_output = false) {
 	return _hash_hmac($algo, $data, $key, $raw_output);
Index: wp-includes/post.php
===================================================================
--- wp-includes/post.php	(revision 21088)
+++ wp-includes/post.php	(working copy)
@@ -2850,7 +2850,9 @@
 		if ( $post_name_check || in_array( $slug, $feeds ) || apply_filters( 'wp_unique_post_slug_is_bad_attachment_slug', false, $slug ) ) {
 			$suffix = 2;
 			do {
-				$alt_post_name = substr ($slug, 0, 200 - ( strlen( $suffix ) + 1 ) ) . "-$suffix";
+				$slug = urldecode( $slug );
+				$length = min( 200, mb_strlen( $slug ) );
+				$alt_post_name = urlencode( mb_substr( $slug, 0, $length - ( strlen( $suffix ) + 1 ) ) . "-$suffix" );
 				$post_name_check = $wpdb->get_var( $wpdb->prepare($check_sql, $alt_post_name, $post_ID ) );
 				$suffix++;
 			} while ( $post_name_check );
@@ -2865,7 +2867,9 @@
 		if ( $post_name_check || in_array( $slug, $feeds ) || preg_match( "@^($wp_rewrite->pagination_base)?\d+$@", $slug )  || apply_filters( 'wp_unique_post_slug_is_bad_hierarchical_slug', false, $slug, $post_type, $post_parent ) ) {
 			$suffix = 2;
 			do {
-				$alt_post_name = substr( $slug, 0, 200 - ( strlen( $suffix ) + 1 ) ) . "-$suffix";
+				$slug = urldecode( $slug );
+				$length = min( 200, mb_strlen( $slug ) );
+				$alt_post_name = urlencode( mb_substr( $slug, 0, $length - ( strlen( $suffix ) + 1 ) ) . "-$suffix" );
 				$post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, $alt_post_name, $post_ID, $post_parent ) );
 				$suffix++;
 			} while ( $post_name_check );
@@ -2879,7 +2883,9 @@
 		if ( $post_name_check || in_array( $slug, $feeds ) || apply_filters( 'wp_unique_post_slug_is_bad_flat_slug', false, $slug, $post_type ) ) {
 			$suffix = 2;
 			do {
-				$alt_post_name = substr( $slug, 0, 200 - ( strlen( $suffix ) + 1 ) ) . "-$suffix";
+				$slug = urldecode( $slug );
+				$length = min( 200, mb_strlen( $slug ) );
+				$alt_post_name = urlencode( mb_substr( $slug, 0, $length - ( strlen( $suffix ) + 1 ) ) . "-$suffix" );
 				$post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, $alt_post_name, $post_type, $post_ID ) );
 				$suffix++;
 			} while ( $post_name_check );
