Database: Throw a notice if `wpdb::prepare()` is called with an incorrect number of arguments

`wpdb::prepare()` currently gives no information if the number of arguments passed doesn't match the number of placeholders in the query. This change gives an explicit notice that the call was incorrect.

Also fixes an enrelated term meta test that was triggering this new notice.

Props thekt12 for the initial patch.
Fixes #42040.


Built from https://develop.svn.wordpress.org/trunk@41662


git-svn-id: http://core.svn.wordpress.org/trunk@41496 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
Gary Pendergast 2017-10-02 02:11:47 +00:00
parent abdfe59c28
commit 1603a9e067
2 changed files with 16 additions and 3 deletions

View File

@ -4,7 +4,7 @@
*
* @global string $wp_version
*/
$wp_version = '4.9-alpha-41661';
$wp_version = '4.9-alpha-41662';
/**
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.

View File

@ -1251,7 +1251,20 @@ class wpdb {
$query = str_replace( '"%s"', '%s', $query ); // doublequote unquoting
$query = preg_replace( '|(?<!%)%f|' , '%F', $query ); // Force floats to be locale unaware
$query = preg_replace( '|(?<!%)%s|', "'%s'", $query ); // quote the strings, avoiding escaped strings like %%s
$query = preg_replace( '/%(?:%|$|([^dsF]))/', '%%\\1', $query ); // escape any unescaped percents
$query = preg_replace( '/%(?:%|$|([^dsF]))/', '%%\\1', $query ); // escape any unescaped percents
// Count the number of valid placeholders in the query
$placeholders = preg_match_all( '/(^|[^%]|(%%)+)%[sdF]/', $query );
if ( count ( $args ) !== $placeholders ) {
_doing_it_wrong( 'wpdb::prepare',
sprintf( __( 'The query does not contain the correct number of placeholders (%d) for the number of arguments passed (%d).' ),
$placeholders,
count( $args ) ),
'4.9.0'
);
}
array_walk( $args, array( $this, 'escape_by_ref' ) );
return @vsprintf( $query, $args );
}
@ -2046,7 +2059,7 @@ class wpdb {
$conditions = implode( ' AND ', $conditions );
$sql = "UPDATE `$table` SET $fields WHERE $conditions";
$this->check_current_query = false;
return $this->query( $this->prepare( $sql, $values ) );
}