Index: wp-includes/shortcodes.php
===================================================================
--- wp-includes/shortcodes.php	(revision 17826)
+++ wp-includes/shortcodes.php	(working copy)
@@ -148,7 +148,7 @@
 		return $content;
 
 	$pattern = get_shortcode_regex();
-	return preg_replace_callback('/'.$pattern.'/s', 'do_shortcode_tag', $content);
+	return preg_replace_callback( "/$pattern/sx", 'do_shortcode_tag', $content );
 }
 
 /**
@@ -174,9 +174,30 @@
 	global $shortcode_tags;
 	$tagnames = array_keys($shortcode_tags);
 	$tagregexp = join( '|', array_map('preg_quote', $tagnames) );
-
-	// WARNING! Do not change this regex without changing do_shortcode_tag() and strip_shortcodes()
-	return '(.?)\[('.$tagregexp.')\b(.*?)(?:(\/))?\](?:(.+?)\[\/\2\])?(.?)';
+	// WARNING! Do not change this regex without changing do_shortcode_tag() and strip_shortcode_tag()
+	return "
+		\\[                                    # Opening bracket
+		(\\[?)                                 # 1: Optional second opening bracket for escaping shortcodes: [[tag]]
+		( $tagregexp )                         # 2: Shortcode name
+		\\b                                    # Word boundary
+		(                                      # 3: Unroll the loop: Inside the opening shortcode tag
+			[^\\]'\"]*                     # Not a closing bracket, single or double quote
+			(?:
+				(?:\"[^\"]*\"|'[^']*') # Anything in quotes
+				[^\\]'\"]*             # Not a closing bracket, single or double quote
+			)*
+		)
+		(\\/?)                                 # 4: Self closing?
+		(?(4)                                  # If self closing, then ...
+			\\]                            # ... Closing bracket
+			|                              # Else ...
+			(?:
+				(.+?)                  # 5: ... Anything between the opening and closing shortcode tags
+				\\[\\/\\2\\]           # ... Closing shortcode tag
+			)?
+		)
+		(.?)                                   # 6: Trailing character
+	";
 }
 
 /**
@@ -203,10 +224,10 @@
 
 	if ( isset( $m[5] ) ) {
 		// enclosing tag - extra parameter
-		return $m[1] . call_user_func( $shortcode_tags[$tag], $attr, $m[5], $tag ) . $m[6];
+		return call_user_func( $shortcode_tags[$tag], $attr, $m[5], $tag ) . $m[6];
 	} else {
 		// self-closing tag
-		return $m[1] . call_user_func( $shortcode_tags[$tag], $attr, NULL,  $tag ) . $m[6];
+		return call_user_func( $shortcode_tags[$tag], $attr, NULL,  $tag ) . $m[6];
 	}
 }
 
@@ -290,9 +311,18 @@
 
 	$pattern = get_shortcode_regex();
 
-	return preg_replace('/'.$pattern.'/s', '$1$6', $content);
+	return preg_replace_callback( "/$pattern/sx", 'strip_shortcode_tag', $content );
 }
 
+function strip_shortcode_tag( $m ) {
+	// allow [[foo]] syntax for escaping a tag
+	if ( $m[1] == '[' && $m[6] == ']' ) {
+		return substr($m[0], 1, -1);
+	}
+
+	return $m[6];
+} 
+
 add_filter('the_content', 'do_shortcode', 11); // AFTER wpautop()
 
-?>
\ No newline at end of file
+?>
Index: wp-includes/formatting.php
===================================================================
--- wp-includes/formatting.php	(revision 17826)
+++ wp-includes/formatting.php	(working copy)
@@ -232,16 +232,44 @@
  * @param string $pee The content.
  * @return string The filtered content.
  */
-function shortcode_unautop($pee) {
+function shortcode_unautop( $pee ) {
 	global $shortcode_tags;
 
-	if ( !empty($shortcode_tags) && is_array($shortcode_tags) ) {
-		$tagnames = array_keys($shortcode_tags);
-		$tagregexp = join( '|', array_map('preg_quote', $tagnames) );
-		$pee = preg_replace('/<p>\\s*?(\\[(' . $tagregexp . ')\\b.*?\\/?\\](?:.+?\\[\\/\\2\\])?)\\s*<\\/p>/s', '$1', $pee);
+	if ( empty( $shortcode_tags ) || !is_array( $shortcode_tags ) ) {
+		return $pee;
 	}
 
-	return $pee;
+	$tagregexp = join( '|', array_map( 'preg_quote', array_keys( $shortcode_tags ) ) );
+
+	$pattern = "/
+		<p>                                            # Opening paragraph
+		\\s*?                                          # Optional leading whitespace
+		(                                              # 1: The shortcode
+			\\[                                    # Opening bracket
+			(?: $tagregexp )                       # Shortcode name
+			\\b                                    # Word boundary
+			(?:                                    # Unroll the loop: Inside the opening shortcode tag
+				[^\\]'\"]*                     # Not a closing bracket, single or double quote
+				(?:
+					(?:\"[^\"]*\"|'[^']*') # Anything in quotes
+					[^\\]'\"]*             # Not a closing bracket, single or double quote
+				)*
+			)
+			(\\/?)                                 # 2: Self closing?
+			(?(2)                                  # If self closing, then ...
+				\\]                            # ... Closing bracket
+				|                              # Else ...
+				(?:
+					.+?                    # ... Anything between the opening and closing shortcode tags
+					\\[\\/\\2\\]           # ... Closing shortcode tag
+				)
+			)?
+		)
+		\\s*                                           # optional trailing whitespace
+		<\\/p>                                         # closing paragraph
+	/sx";
+
+	return preg_replace( $pattern, '$1', $pee );
 }
 
 /**
