Index: src/wp-includes/formatting.php
===================================================================
--- src/wp-includes/formatting.php	(revision 29764)
+++ src/wp-includes/formatting.php	(working copy)
@@ -28,7 +28,7 @@
  * @return string The string replaced with html entities
  */
 function wptexturize($text, $reset = false) {
-	global $wp_cockneyreplace, $shortcode_tags;
+	global $wp_cockneyreplace;
 	static $static_characters, $static_replacements, $dynamic_characters, $dynamic_replacements,
 		$default_no_texturize_tags, $default_no_texturize_shortcodes, $run_texturize = true;
 
@@ -205,26 +205,34 @@
 
 	// Look for shortcodes and HTML elements.
 
-	$tagnames = array_keys( $shortcode_tags );
-	$tagregexp = join( '|', array_map( 'preg_quote', $tagnames ) );
-	$tagregexp = "(?:$tagregexp)(?![\\w-])"; // Excerpt of get_shortcode_regex().
+	$comment_regex = 
+			'!--'			// Start of comment, after the <.
+		.	'[^\-]*'		// Consume non-dashes.
+		.	'(?:'			// Unroll the loop: Consume everything until --> is found.
+		.		'-(?!->)'	// Dash not followed by end of comment.
+		.		'[^\-]*+'	// Consume non-dashes.
+		.	')*+'			// Loop possessively.
+		.	'(?:-->)?';		// End of comment. If not found, match all input.
 	
-	$regex =  '/('			// Capture the entire match.
-		.	'<'		// Find start of element.
-		.	'(?(?=!--)'	// Is this a comment?
-		.		'.+?--\s*>'	// Find end of comment
+	$shortcode_regex =
+			'\['			// Find start of shortcode.
+		.	'[\/\[]?'		// Shortcodes may begin with [/ or [[
+		.	'[^\s\/\[\]]'	// No whitespace before name.
+		.	'[^\[\]]*+'		// Shortcodes do not contain other shortcodes. Possessive critical.
+		.	'\]'			// Find end of shortcode.
+		.	'\]?';			// Shortcodes may end with ]]
+	
+	$regex = 
+			'/('					// Capture the entire match.
+		.		'<'					// Find start of element.
+		.		'(?(?=!--)'			// Is this a comment?
+		.			$comment_regex	// Find end of comment.
+		.		'|'
+		.			'[^>]+>'		// Find end of element.
+		.		')'
 		.	'|'
-		.		'[^>]+>'	// Find end of element
-		.	')'
-		. '|'
-		.	'\['		// Find start of shortcode.
-		.	'\[?'		// Shortcodes may begin with [[
-		.	'\/?'		// Closing slash may precede name.
-		.	$tagregexp	// Only match registered shortcodes, because performance.
-		.	'[^\[\]]*'	// Shortcodes do not contain other shortcodes.
-		.	'\]'		// Find end of shortcode.
-		.	'\]?'		// Shortcodes may end with ]]
-		. ')/s';
+		.		$shortcode_regex	// Find shortcodes.
+		.	')/s';
 
 	$textarr = preg_split( $regex, $text, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY );
 
@@ -231,19 +239,22 @@
 	foreach ( $textarr as &$curl ) {
 		// Only call _wptexturize_pushpop_element if $curl is a delimiter.
 		$first = $curl[0];
-		if ( '<' === $first && '>' === substr( $curl, -1 ) ) {
-			// This is an HTML delimiter.
+		if ( '<' === $first && '<!--' === substr( $curl, 0, 4 ) ) {
+			// This is an HTML comment delimeter.
 
-			if ( '<!--' !== substr( $curl, 0, 4 ) ) {
-				_wptexturize_pushpop_element( $curl, $no_texturize_tags_stack, $no_texturize_tags );
-			}
+			continue;
 
+		} elseif ( '<' === $first && '>' === substr( $curl, -1 ) ) {
+			// This is an HTML element delimiter.
+
+			_wptexturize_pushpop_element( $curl, $no_texturize_tags_stack, $no_texturize_tags );
+
 		} elseif ( '' === trim( $curl ) ) {
 			// This is a newline between delimiters.  Performance improves when we check this.
 
 			continue;
 
-		} elseif ( '[' === $first && 1 === preg_match( '/^\[\[?\/?' . $tagregexp . '[^\[\]]*\]\]?$/', $curl ) ) {
+		} elseif ( '[' === $first && 1 === preg_match( '/^' . $shortcode_regex . '$/', $curl ) ) {
 			// This is a shortcode delimiter.
 
 			if ( '[[' !== substr( $curl, 0, 2 ) && ']]' !== substr( $curl, -2 ) ) {
Index: src/wp-includes/shortcodes.php
===================================================================
--- src/wp-includes/shortcodes.php	(revision 29764)
+++ src/wp-includes/shortcodes.php	(working copy)
@@ -231,7 +231,7 @@
 	$tagregexp = join( '|', array_map('preg_quote', $tagnames) );
 
 	// WARNING! Do not change this regex without changing do_shortcode_tag() and strip_shortcode_tag()
-	// Also, see shortcode_unautop() and shortcode.js and wptexturize().
+	// Also, see shortcode_unautop() and shortcode.js.
 	return
 		  '\\['                              // Opening bracket
 		. '(\\[?)'                           // 1: Optional second opening bracket for escaping shortcodes: [[tag]]
Index: tests/phpunit/tests/formatting/WPTexturize.php
===================================================================
--- tests/phpunit/tests/formatting/WPTexturize.php	(revision 29764)
+++ tests/phpunit/tests/formatting/WPTexturize.php	(working copy)
@@ -1188,14 +1188,30 @@
 	function data_tag_avoidance() {
 		return array(
 			array(
+				'[ ... ]',
+				'[ &#8230; ]',
+			),
+			array(
 				'[ is it wise to <a title="allow user content ] here? hmm"> maybe </a> ]',
 				'[ is it wise to <a title="allow user content ] here? hmm"> maybe </a> ]',
 			),
 			array(
+				'[is it wise to <a title="allow user content ] here? hmm"> maybe </a> ]', // HTML corruption is a known bug.  See tickets #12690 and #29557.
+				'[is it wise to <a title="allow user content ] here? hmm&#8221;> maybe </a> ]',
+			),
+			array(
+				'[caption - is it wise to <a title="allow user content ] here? hmm"> maybe </a> ]',
+				'[caption - is it wise to <a title="allow user content ] here? hmm&#8221;> maybe </a> ]',
+			),
+			array(
 				'[ photos by <a href="http://example.com/?a[]=1&a[]=2"> this guy </a> ]',
 				'[ photos by <a href="http://example.com/?a[]=1&#038;a[]=2"> this guy </a> ]',
 			),
 			array(
+				'[photos by <a href="http://example.com/?a[]=1&a[]=2"> this guy </a>]',
+				'[photos by <a href="http://example.com/?a[]=1&#038;a[]=2"> this guy </a>]',
+			),
+			array(
 				'[gallery ...]',
 				'[gallery ...]',
 			),
@@ -1212,10 +1228,6 @@
 				'[/gallery ...]',
 			),
 			array(
-				'[...]...[/...]', // These are potentially usable shortcodes.
-				'[&#8230;]&#8230;[/&#8230;]',
-			),
-			array(
 				'[[gallery]]...[[/gallery]]', // Shortcode parsing will ignore the inner ]...[ part and treat this as a single escaped shortcode.
 				'[[gallery]]&#8230;[[/gallery]]',
 			),
@@ -1224,10 +1236,6 @@
 				'[[[gallery]]]&#8230;[[[/gallery]]]',
 			),
 			array(
-				'[gal>ery ...]',
-				'[gal>ery &#8230;]',
-			),
-			array(
 				'[gallery ...',
 				'[gallery &#8230;',
 			),
@@ -1300,10 +1308,14 @@
 				'<!--...-->',
 			),
 			array(
-				'<!-- ... -- >',
-				'<!-- ... -- >',
+				'<!-- ... -- > ...',
+				'<!-- ... -- > ...',
 			),
 			array(
+				'<!-- ...', // An unclosed comment is still a comment.
+				'<!-- ...',
+			),
+			array(
 				'<!-- <br /> [gallery] ... -->',
 				'<!-- <br /> [gallery] ... -->',
 			),
@@ -1727,13 +1739,25 @@
 			),
 			array(
 				'[code ...]...[/code]', // code is not a registered shortcode.
-				'[code &#8230;]&#8230;[/code]',
+				'[code ...]...[/code]',
 			),
 			array(
 				'[hello ...]...[/hello]', // hello is not a registered shortcode.
-				'[hello &#8230;]&#8230;[/hello]',
+				'[hello ...]&#8230;[/hello]',
 			),
 			array(
+				'[...]...[/...]', // These are potentially usable shortcodes.
+				'[...]&#8230;[/...]',
+			),
+			array(
+				'[gal>ery ...]',
+				'[gal>ery ...]',
+			),
+			array(
+				'[randomthing param="test"]',
+				'[randomthing param="test"]',
+			),
+			array(
 				'[[audio]...[/audio]...', // These are potentially usable shortcodes.  Unfortunately, the meaning of [[audio] is ambiguous unless we run the entire shortcode regexp.
 				'[[audio]&#8230;[/audio]&#8230;',
 			),
