Index: default-widgets.php
===================================================================
--- default-widgets.php	(revision 12543)
+++ default-widgets.php	(working copy)
@@ -805,8 +805,16 @@
 		if ( empty($title) )
 			$title = __('Untitled');
 
-		$desc = str_replace(array("\n", "\r"), ' ', esc_attr(strip_tags(@html_entity_decode($item->get_description(), ENT_QUOTES, get_option('blog_charset')))));
-		$desc = wp_html_excerpt( $desc, 360 ) . ' [&hellip;]';
+		$desc = str_replace( array("\n", "\r"), ' ', esc_attr( strip_tags( @html_entity_decode( $item->get_description(), ENT_QUOTES, get_option('blog_charset') ) ) ) );
+		$desc = wp_html_excerpt( $desc, 360 );
+
+		// Append ellipsis if there isn't one at the end already.
+		// Change an existing [...] at the end of an excerpt to [&hellip;].
+		if ( !preg_match( '/(\[&hellip;\]|\[...\])$/D', $desc ) )
+			$desc .= ' [&hellip;]';
+		else
+			$desc = preg_replace( '/\[...\]$/D', ' [&hellip;]', $desc );
+
 		$desc = esc_html( $desc );
 
 		if ( $show_summary ) {
