Index: wp-db.php
===================================================================
--- wp-db.php	(revision 12541)
+++ wp-db.php	(working copy)
@@ -533,6 +533,8 @@
 	 * Prepares a SQL query for safe execution.  Uses sprintf()-like syntax.
 	 *
 	 * This function only supports a small subset of the sprintf syntax; it only supports %d (decimal number), %s (string).
+	 * All % characters inside $query string literals, including LIKE wildcards, must be double %-escaped as %%.
+	 *
 	 * Does not support sign, padding, alignment, width or precision specifiers.
 	 * Does not support argument numbering/swapping.
 	 *
@@ -541,9 +543,12 @@
 	 * Both %d and %s should be left unquoted in the query string.
 	 *
 	 * <code>
-	 * wpdb::prepare( "SELECT * FROM `table` WHERE `column` = %s AND `field` = %d", "foo", 1337 )
+	 * $wpdb->prepare( "SELECT * FROM `table` WHERE `column` = %s AND `field` = %d", "foo", 1337 );
+	 * $wpdb->prepare( "UPDATE $wpdb->posts SET guid = '100%% Satisfied' WHERE ID = %s", $stringin );
 	 * </code>
 	 *
+	 * Care must be taken not to allow direct user input to the second param, which enables array manipulation.
+	 *
 	 * @link http://php.net/sprintf Description of syntax.
 	 * @since 2.3.0
 	 *
@@ -562,7 +567,7 @@
 			$args = $args[0];
 		$query = str_replace("'%s'", '%s', $query); // in case someone mistakenly already singlequoted it
 		$query = str_replace('"%s"', '%s', $query); // doublequote unquoting
-		$query = str_replace('%s', "'%s'", $query); // quote the strings
+		$query = preg_replace('|(?<!%)%s|', "'%s'", $query); //quote the strings, Avoiding escaped strings
 		array_walk($args, array(&$this, 'escape_by_ref'));
 		return @vsprintf($query, $args);
 	}
