#22262 closed defect (bug) (fixed)
Possible invalid uses of wpdb::prepare()
| Reported by: | xknown | Owned by: | nacin |
|---|---|---|---|
| Priority: | normal | Milestone: | 3.5 |
| Component: | Database | Version: | |
| Severity: | normal | Keywords: | has-patch |
| Cc: | Focuses: |
Description
One common error I see about wpdb::prepare() is that many developers tend to use it by passing only a SQL query, which may produce bugs due to the implementation of this method.
As you know, wpdb::prepare() does, generally speaking, a string replacement of the placeholders (%s, %d, etc) by using sprintf/vsprintf under the scenes. So, if one passes a SQL query with placeholders and no other parameters, then this method returns a blank string. For example:
$query = $wpdb->prepare( 'select * from table where column = %s', $user_input ); $result_set = $wpdb->get_results( $wpdb->prepare( $query ) );
If $user_input contains a placeholder (i.e. "hola%s mundo"), the query will not be executed.
I used a simple static code analyzer to detect this calls on the core and found two instances.
- http://core.trac.wordpress.org/browser/trunk/wp-includes/query.php#L2409
- http://core.trac.wordpress.org/browser/trunk/wp-includes/ms-functions.php#L1922
We should call _doing_it_wrong() if wpdb::prepare() receives only one parameter.
Attachments (1)
Change History (11)
#2
in reply to: ↑ 1
@
14 years ago
Replying to nacin:
I agree on all counts.
What if we declared prepare() with a second argument, automatically causing E_WARNINGs? Might not be the prettiest for sites that show errors. (Maybe after having notices there for a few releases?)
I think is okay to add another required parameter. However, we can also remove the @ of @vsprintf( $query, $args ) in prepare(), which is the one that hides the PHP warning produced by this invalid uses.
#6
@
14 years ago
In wp-db.php with a second parameter required, the call to isset() inside of prepare() is no longer required. Removing it is an option, although it would cause a second PHP debug message when called with only one param.
#9
@
14 years ago
Looks like somebody didn't tell Akismet. In Akismet admin.php:
$waiting = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $wpdb->commentmeta WHERE meta_key = 'akismet_error'" ) );
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)
I agree on all counts.
What if we declared prepare() with a second argument, automatically causing E_WARNINGs? Might not be the prettiest for sites that show errors. (Maybe after having notices there for a few releases?)