- Patch #9478 by JonBob: allow printf-style arguments in pager_query.

Currently pager_query() is the black sheep of the database query family, because it does not allow for printf-style arguments to be inserted in the query. This is a problem because it introduces developer confusion when moving from an unpaged query to a paged one, and it encourages substitution of variables directly into the query, which can bypass our check_query() security feature.

  This patch adds this ability to pager_query(). The change is backwards-compatible, but a couple calls to the function in core have been changed to use the new capability.
4.5.x
Dries Buytaert 2004-07-25 14:25:42 +00:00
parent d8d524ffef
commit 702a057683
8 changed files with 27 additions and 23 deletions

View File

@ -17,7 +17,7 @@ LEGEND
--------------------------------------------------------------------------------
BLOG API
M:James Walker <walkah@walkah.net>
M: James Walker <walkah@walkah.net>
S: maintained
CODING STYLE CHECKER
@ -32,6 +32,14 @@ LOCALE MODULE
M: Gabor Hojtsy <goba@php.net>
S: maintained
MENU SYSTEM
M: Jonathan Chaffer <jchaffer@structureinteractive.com>
S: maintained
PATH MODULE
M: Matt Westgate <drupal@asitis.org>
S: maintained
POSTGRES PORT
M: Adrian Rossouw <adrian@obsidian.co.za>
S: maintained
@ -40,10 +48,6 @@ STATISTICS MODULE
M: Jeremy Andrews <jeremy@kerneltrap.com>
S: maintained
USER SYSTEM
M: Moshe Weitzman <weitzman@tejasa.com>
S: maintained
DEBIAN PACKAGE
M: Hilko Bengen <bengen@debian.org>
S: maintained

View File

@ -38,27 +38,31 @@
* An optional integer to distinguish between multiple pagers on one page.
* @param $count_query
* An SQL query used to count matching records.
* @param ...
* A variable number of arguments which are substituted into the query (and
* also the count query) using printf() syntax.
* @return
* A database query result resource, or FALSE if the query was not executed
* correctly.
*/
function pager_query($query, $limit = 10, $element = 0, $count_query = '') {
function pager_query($query, $limit = 10, $element = 0, $count_query = NULL) {
global $pager_from_array, $pager_total;
$from = $_GET['from'];
// Substitute in query arguments.
$args = func_get_args();
$args = array_slice($args, 4);
// Count the total number of records in this query.
if ($count_query == '') {
$pager_total[$element] = db_result(db_query(preg_replace(array('/SELECT.*FROM/is', '/ORDER BY .*/'), array('SELECT COUNT(*) FROM', ''), $query)));
}
else {
$pager_total[$element] = db_result(db_query($count_query));
if (!isset($count_query)) {
$count_query = preg_replace(array('/SELECT.*FROM/is', '/ORDER BY .*/'), array('SELECT COUNT(*) FROM', ''), $query);
}
$pager_total[$element] = db_result(call_user_func_array('db_query', array_merge(array($count_query), $args)));
// Convert comma-separated $from to an array, used by other functions.
$pager_from_array = explode(',', $from);
return db_query_range($query, (int)$pager_from_array[$element], (int)$limit);
return call_user_func_array('db_query_range', array_merge(array($query), $args, array((int)$pager_from_array[$element], (int)$limit)));
}
/**

View File

@ -143,7 +143,7 @@ function blog_page_user($uid) {
$title = t("%name's blog", array('%name' => $account->name));
$output = '';
$result = pager_query("SELECT nid FROM {node} WHERE type = 'blog' AND uid = '$account->uid' AND status = 1 ORDER BY sticky DESC, created DESC", variable_get('default_nodes_main', 10));
$result = pager_query("SELECT nid FROM {node} WHERE type = 'blog' AND uid = %d AND status = 1 ORDER BY sticky DESC, created DESC", variable_get('default_nodes_main', 10), 0, NULL, $account->uid);
while ($node = db_fetch_object($result)) {
$output .= node_view(node_load(array('nid' => $node->nid)), 1);
}

View File

@ -143,7 +143,7 @@ function blog_page_user($uid) {
$title = t("%name's blog", array('%name' => $account->name));
$output = '';
$result = pager_query("SELECT nid FROM {node} WHERE type = 'blog' AND uid = '$account->uid' AND status = 1 ORDER BY sticky DESC, created DESC", variable_get('default_nodes_main', 10));
$result = pager_query("SELECT nid FROM {node} WHERE type = 'blog' AND uid = %d AND status = 1 ORDER BY sticky DESC, created DESC", variable_get('default_nodes_main', 10), 0, NULL, $account->uid);
while ($node = db_fetch_object($result)) {
$output .= node_view(node_load(array('nid' => $node->nid)), 1);
}

View File

@ -83,7 +83,7 @@ function profile_browse() {
}
// Extract the affected users:
$result = pager_query("SELECT u.uid FROM {users} u INNER JOIN {profile_values} v ON u.uid = v.uid WHERE v.fid = $field->fid AND $query ORDER BY u.changed DESC", 20);
$result = pager_query("SELECT u.uid FROM {users} u INNER JOIN {profile_values} v ON u.uid = v.uid WHERE v.fid = %d AND $query ORDER BY u.changed DESC", 20, 0, NULL, $field->fid);
$output = '<div id="profile">';
while ($account = db_fetch_object($result)) {

View File

@ -83,7 +83,7 @@ function profile_browse() {
}
// Extract the affected users:
$result = pager_query("SELECT u.uid FROM {users} u INNER JOIN {profile_values} v ON u.uid = v.uid WHERE v.fid = $field->fid AND $query ORDER BY u.changed DESC", 20);
$result = pager_query("SELECT u.uid FROM {users} u INNER JOIN {profile_values} v ON u.uid = v.uid WHERE v.fid = %d AND $query ORDER BY u.changed DESC", 20, 0, NULL, $field->fid);
$output = '<div id="profile">';
while ($account = db_fetch_object($result)) {

View File

@ -44,9 +44,7 @@ function tracker_page($uid = 0) {
$output .= '';
if ($uid) {
$uid = check_query($uid);
$result = pager_query("SELECT n.nid, n.title, n.type, n.changed, n.uid, u.name, MAX(GREATEST(n.changed, c.timestamp)) AS last_post FROM {node} n LEFT JOIN {comments} c ON n.nid = c.nid INNER JOIN {users} u ON n.uid = u.uid WHERE n.status = 1 AND (n.uid = $uid OR c.uid = $uid) GROUP BY n.nid, n.title, n.type, n.changed, n.uid, u.name ORDER BY last_post DESC", 25, 0, "SELECT COUNT(DISTINCT(n.nid)) FROM {node} n LEFT JOIN {comments} c ON n.nid = c.nid WHERE n.status = 1 AND (n.uid = $uid OR c.uid = $uid)");
$result = pager_query('SELECT n.nid, n.title, n.type, n.changed, n.uid, u.name, MAX(GREATEST(n.changed, c.timestamp)) AS last_post FROM {node} n LEFT JOIN {comments} c ON n.nid = c.nid INNER JOIN {users} u ON n.uid = u.uid WHERE n.status = 1 AND (n.uid = %d OR c.uid = %d) GROUP BY n.nid, n.title, n.type, n.changed, n.uid, u.name ORDER BY last_post DESC', 25, 0, 'SELECT COUNT(DISTINCT(n.nid)) FROM {node} n LEFT JOIN {comments} c ON n.nid = c.nid WHERE n.status = 1 AND (n.uid = %d OR c.uid = %d)', $uid, $uid);
}
else {

View File

@ -44,9 +44,7 @@ function tracker_page($uid = 0) {
$output .= '';
if ($uid) {
$uid = check_query($uid);
$result = pager_query("SELECT n.nid, n.title, n.type, n.changed, n.uid, u.name, MAX(GREATEST(n.changed, c.timestamp)) AS last_post FROM {node} n LEFT JOIN {comments} c ON n.nid = c.nid INNER JOIN {users} u ON n.uid = u.uid WHERE n.status = 1 AND (n.uid = $uid OR c.uid = $uid) GROUP BY n.nid, n.title, n.type, n.changed, n.uid, u.name ORDER BY last_post DESC", 25, 0, "SELECT COUNT(DISTINCT(n.nid)) FROM {node} n LEFT JOIN {comments} c ON n.nid = c.nid WHERE n.status = 1 AND (n.uid = $uid OR c.uid = $uid)");
$result = pager_query('SELECT n.nid, n.title, n.type, n.changed, n.uid, u.name, MAX(GREATEST(n.changed, c.timestamp)) AS last_post FROM {node} n LEFT JOIN {comments} c ON n.nid = c.nid INNER JOIN {users} u ON n.uid = u.uid WHERE n.status = 1 AND (n.uid = %d OR c.uid = %d) GROUP BY n.nid, n.title, n.type, n.changed, n.uid, u.name ORDER BY last_post DESC', 25, 0, 'SELECT COUNT(DISTINCT(n.nid)) FROM {node} n LEFT JOIN {comments} c ON n.nid = c.nid WHERE n.status = 1 AND (n.uid = %d OR c.uid = %d)', $uid, $uid);
}
else {