Support using integers as booleans in expressions

For MySQL compatibility, support using integers as booleans in
expressions.  This is an expensive and unreliable check, so limit it to
the cases currently observed in the wild.  We can expand the checks
later if more uses appear.

The current appearance is from the query:

SELECT SQL_CALC_FOUND_ROWS  wp_posts.ID FROM wp_posts  WHERE 1=1 AND 0
ORDER BY wp_posts.post_date DESC LIMIT 0, 10

made by require('wp-blog-header.php'), wp, WP->main, WP->query_posts,
WP_Query->query, WP_Query->get_posts

I can't determine the exact source of the calls or whether it is
URL-dependent.  But for me that is irrelevant, since it is a case that I
need to support.

Signed-off-by: Kevin Locke <kevin@kevinlocke.name>
This commit is contained in:
Kevin Locke
2015-10-02 14:02:31 -07:00
parent 33740e34e5
commit 3a5afabcae

View File

@ -321,7 +321,21 @@
// Akismet sometimes doesn't write 'comment_ID' with 'ID' in capitals where needed ...
if( false !== strpos( $sql, $wpdb->comments))
$sql = str_replace(' comment_id ', ' comment_ID ', $sql);
// MySQL allows integers to be used as boolean expressions
// where 0 is false and all other values are true.
//
// Although this could occur anywhere with any number, so far it
// has only been observed as top-level expressions in the WHERE
// clause and only with 0. For performance, limit current
// replacements to that.
$pattern_after_where = '(?:\s*$|\s+(GROUP|HAVING|ORDER|LIMIT|PROCEDURE|INTO|FOR|LOCK))';
$pattern = '/(WHERE\s+)0(\s+AND|\s+OR|' . $pattern_after_where . ')/';
$sql = preg_replace( $pattern, '$1false$2', $sql);
$pattern = '/(AND\s+|OR\s+)0(' . $pattern_after_where . ')/';
$sql = preg_replace( $pattern, '$1false$2', $sql);
// MySQL supports strings as names, PostgreSQL needs identifiers.
// Limit to after closing parenthesis to reduce false-positives
// Currently only an issue for nextgen-gallery plugin