[wp-trac] [WordPress Trac] #42040: `$wpdb->prepare` returns blank without notice if less number of arguments are passed. should give a notice or exception
WordPress Trac
noreply at wordpress.org
Sat Sep 30 06:20:34 UTC 2017
#42040: `$wpdb->prepare` returns blank without notice if less number of arguments
are passed. should give a notice or exception
--------------------------+-----------------------------
Reporter: thekt12 | Owner:
Type: defect (bug) | Status: new
Priority: normal | Milestone: Awaiting Review
Component: Query | Version: 4.8.2
Severity: normal | Keywords:
Focuses: |
--------------------------+-----------------------------
1.A '''`Right Case`''':
{{{#!php
<?php
$wpdb->prepare("select * from wp_posts where ID=%d and post_type=%s",
array("1","post"))
}}}
Returns:[[BR]]
`select * from wp_posts where ID=1 and post_type='post'`[[BR]]
which is right[[BR]]
2.A '''`Right Case`''':
{{{#!php
<?php
$wpdb->prepare("select * from wp_posts where ID=%d and
post_type=%s",1,"post")
}}}
Returns:[[BR]]
`select * from wp_posts where ID=1 and post_type='post'`[[BR]]
which is also right[[BR]]
3.A '''`Semi Right Case`''':
{{{#!php
<?php
$wpdb->prepare("select * from wp_posts where ID=%d and post_type=%s",
array("1","post","xyz"))
}}}
Returns:[[BR]]
`select * from wp_posts where ID=1 and post_type='post'`[[BR]]
understood it ignore extra attributes('''`but could give a notice`'''- i
do understand that it is hard to find out in this case)[[BR]]
[[BR]]
'''But''' : [[BR]]
[[BR]]
3.A '''`Wrong Case`''' (Case with less argument passed in ) :
{{{
$wpdb->prepare("select * from wp_posts where ID=%d and post_type=%s",
array("1"))
}}}
Returns:[[BR]]
`blank`[[BR]]
It should either `give a notice` or `an exception`. If it returns blank,
it actually hides the actual problem.
[[BR]]
How serious is this issue?
Think of the following snippet:
{{{#!php
<?php
//this will return a blank without exception
$statement = $wpdb->prepare("select * from wp_posts where ID=%d and
post_type=%s", array("1"));
// This will also return blank if blank string is passed in
$results = $wpdb->get_results($statement);
/* so the developer assumes that the result for this query is blank
instead of the fact that this is caused due to a wrong number of argument
that he has passed in.
This is bound to happen in a large query.
*/
}}}
I am yet to figure out the actual way but following code (though not fool
proof) will work:
{{{#!php
<?php
public function prepare($query, $args)
{
if (is_null($query)) {
return;
}
// This is not meant to be foolproof -- but it will catch
obviously incorrect usage.
if (strpos($query, '%') === false) {
_doing_it_wrong('wpdb::prepare', sprintf(__('The query
argument of %s must have a placeholder.'), 'wpdb::prepare()'), '3.9.0');
}
$args = func_get_args();
array_shift($args);
// If args were passed as an array (as in vsprintf), move them up
if (is_array($args[0]) && count($args) == 1) {
$args = $args[0];
}
foreach ($args as $arg) {
if (! is_scalar($arg) && ! is_null($arg)) {
_doing_it_wrong('wpdb::prepare', sprintf('Unsupported
value type (%s).', gettype($arg)), '4.8.2');
}
}
$query = str_replace("'%s'", '%s', $query); // in case someone
mistakenly already singlequoted it
$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
array_walk($args, array( $this, 'escape_by_ref' ));
// my modification to wp-includes/wp-db.php function prepare()
$statement = @vsprintf($query, $args);
if(empty($statement) && !empty($query))
{
_doing_it_wrong('wpdb::prepare', "Improper prepare statemnt.
Check the number of argument passed in" , '4.*.*');
}
return $statement;
}
}}}
// will try to provied a better solution for this
--
Ticket URL: <https://core.trac.wordpress.org/ticket/42040>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform
More information about the wp-trac
mailing list