### Eclipse Workspace Patch 1.0
#P wordpress
Index: wp-includes/post-template.php
===================================================================
--- wp-includes/post-template.php	(revision 11070)
+++ wp-includes/post-template.php	(working copy)
@@ -322,14 +322,16 @@
 	foreach ( (array) get_the_category($post->ID) as $cat ) {
 		if ( empty($cat->slug ) )
 			continue;
-		$classes[] = 'category-' . $cat->slug;
+		$classes[] = 'category-' . urldecode($cat->slug);
+		$classes[] = 'categoryid-' . $cat->term_id;
 	}
 
 	// Tags
 	foreach ( (array) get_the_tags($post->ID) as $tag ) {
 		if ( empty($tag->slug ) )
 			continue;
-		$classes[] = 'tag-' . $tag->slug;
+		$classes[] = 'tag-' . urldecode($tag->slug);	
+		$classes[] = 'tagid-' . $tag->term_id;
 	}
 
 	if ( !empty($class) ) {
@@ -337,6 +339,8 @@
 			$class = preg_split('#\s+#', $class);
 		$classes = array_merge($classes, $class);
 	}
+	
+	$classes = clean_css_classnames($classes, false);
 
 	return apply_filters('post_class', $classes, $class, $post_id);
 }
Index: wp-includes/formatting.php
===================================================================
--- wp-includes/formatting.php	(revision 11070)
+++ wp-includes/formatting.php	(working copy)
@@ -76,6 +76,70 @@
 }
 
 /**
+ * clean invalid chars from css class names
+ * 
+ * invalid chars will be replaced with '_', if the class
+ * should not be treated as a suffix for an existing class,
+ * then invalid classes will be fixed with an additional '_' 
+ * to validate again. 
+ * 
+ * @since 2.8.bleeding
+ * 
+ * @param  array|string $class  array or string with class(es)
+ * @param  bool         $suffix optional wether or not class(es) 
+ * 								are treated as being a suffix 
+ * 								(defaults to true)
+ * @return array|string	classname(es) cleaned  
+ */
+function clean_css_classnames($class, $suffix = true)
+{
+	if (is_array($class)) { // handle multiple class in form of an iterator
+		$return = array();
+		foreach($class as $single)
+			$return[] = clean_css_classnames($single, $suffix);
+		return $return;	
+	}
+	
+		
+	$partsUtf8      = split_utf8($class);
+	$count 			= count($partsUtf8);
+	if (is_array($partsUtf8) && $count != strlen($class)) { // has multi byte chars
+		
+		// filter invalid chars per entity, only single chars need to me checked
+		for ($i=0; $i < $count; $i++) {
+			if (strlen($partsUtf8[$i]) == 1) {
+				$partsUtf8[$i] = preg_replace('|[^_a-zA-Z0-9\0-\177-]|', '_', $partsUtf8[$i]); 
+			}
+		}
+		$class = implode($partsUtf8); // rebuild class string
+	} else {
+		// filter invalid chars in whole string (SBCS assumed)
+		$patternInvalid = '|[^_a-zA-Z0-9\0-\177-]|';
+		$class  = preg_replace($patternInvalid, '_', $class);				
+	}
+	
+	// validate start of the classname (if suffix flag is false)
+	// which must match -?{nmstart} then 
+	if (!$suffix) {
+		// locate nmstart
+		$indexValidate  = ($partsUtf8[0] == '-') ? 1 : 0;
+		// only single-byte sequences need to be checked
+		if (strlen($partsUtf8[$indexValidate]) == 1)		
+		{
+			//valid for nmstart
+			$patternValid = '/[_a-zA-Z\200-\377]/';			
+			if(!preg_match($patternValid, $partsUtf8[$indexValidate]))
+			{
+				$temp  = array_splice($partsUtf8, $indexValidate, 0, array('_'));
+				$class = implode($partsUtf8);
+			}			
+		}	
+	}
+				
+	return $class;
+}
+
+/**
  * Accepts matches array from preg_replace_callback in wpautop() or a string.
  *
  * Ensures that the contents of a <<pre>>...<</pre>> HTML block are not
@@ -166,22 +230,46 @@
  * @param string $Str The string to be checked
  * @return bool True if $Str fits a UTF-8 model, false otherwise.
  */
-function seems_utf8($Str) { # by bmorel at ssi dot fr
-	$length = strlen($Str);
+function seems_utf8(&$str) {	
+	return is_array(split_utf8($str));		
+}
+
+/**
+ * splits a binary string into it's UTF-8 entities
+ * 
+ * NOTE: this function is not confirm with RFC 3629 because
+ * it has been choosen to be compatbile with seems_utf8()
+ * which uses an invalid maximum length of 5 bytes in-
+ * stead of a maxmimum of 4 bytes (or theoretical maximum 
+ * of 8 bytes).
+ * 
+ * @since  2.8.bleeding
+ * 
+ * @see    seems_utf8()
+ * @param  string $str The string to be splitted
+ * @return array  Sequence of UTF-8 entities. False on Failure. 
+ */
+function split_utf8(&$str) {
+	$parts  = array();
+	$length = strlen($str);
 	for ($i=0; $i < $length; $i++) {
-		if (ord($Str[$i]) < 0x80) continue; # 0bbbbbbb
-		elseif ((ord($Str[$i]) & 0xE0) == 0xC0) $n=1; # 110bbbbb
-		elseif ((ord($Str[$i]) & 0xF0) == 0xE0) $n=2; # 1110bbbb
-		elseif ((ord($Str[$i]) & 0xF8) == 0xF0) $n=3; # 11110bbb
-		elseif ((ord($Str[$i]) & 0xFC) == 0xF8) $n=4; # 111110bb
-		elseif ((ord($Str[$i]) & 0xFE) == 0xFC) $n=5; # 1111110b
+		$c = ord($str[$i]); 
+		if ($c < 0x80) $n = 0; # 0bbbbbbb
+		elseif (($c & 0xE0) == 0xC0) $n=1; # 110bbbbb
+		elseif (($c & 0xF0) == 0xE0) $n=2; # 1110bbbb
+		elseif (($c & 0xF8) == 0xF0) $n=3; # 11110bbb
+		elseif (($c & 0xFC) == 0xF8) $n=4; # 111110bb
+		elseif (($c & 0xFE) == 0xFC) $n=5; # 1111110b
 		else return false; # Does not match any model
+		$k = $i;
 		for ($j=0; $j<$n; $j++) { # n bytes matching 10bbbbbb follow ?
-			if ((++$i == $length) || ((ord($Str[$i]) & 0xC0) != 0x80))
-			return false;
-		}
+			if ((++$i == $length) || ((ord($str[$i]) & 0xC0) != 0x80))
+				return false;
+		}				
+		$part    = substr($str, $k, $n+1);
+		$parts[] = $part; 
 	}
-	return true;
+	return $parts;
 }
 
 /**
