Commit be4f6d21 by Scott

Refactor uses of qa_db_escape_string

parent ceada519
...@@ -760,7 +760,7 @@ function qa_db_default_userfields_sql() ...@@ -760,7 +760,7 @@ function qa_db_default_userfields_sql()
$sql = 'INSERT INTO ^userfields (title, position, flags, permit) VALUES'; // content column will be NULL, meaning use default from lang files $sql = 'INSERT INTO ^userfields (title, position, flags, permit) VALUES'; // content column will be NULL, meaning use default from lang files
foreach ($profileFields as $field) { foreach ($profileFields as $field) {
$sql .= sprintf('("%s", %d, %d, %d), ', qa_db_escape_string($field['title']), $field['position'], $field['flags'], $field['permit']); $sql .= sprintf('("%s", %d, %d, %d), ', $field['title'], $field['position'], $field['flags'], $field['permit']);
} }
$sql = substr($sql, 0, -2); $sql = substr($sql, 0, -2);
......
...@@ -48,7 +48,7 @@ function qa_db_points_option_names() ...@@ -48,7 +48,7 @@ function qa_db_points_option_names()
* Returns an array containing all the calculation formulae for the userpoints table. Each element of this * Returns an array containing all the calculation formulae for the userpoints table. Each element of this
* array is for one column - the key contains the column name, and the value is a further array of two elements. * array is for one column - the key contains the column name, and the value is a further array of two elements.
* The element 'formula' contains the SQL fragment that calculates the columns value for one or more users, * The element 'formula' contains the SQL fragment that calculates the columns value for one or more users,
* where the ~ symbol within the fragment is substituted for a constraint on which users we are interested in. * and must contain one placeholder using ? for which the userid is passed as a parameter in the query.
* The element 'multiple' specifies what to multiply each column by to create the final sum in the points column. * The element 'multiple' specifies what to multiply each column by to create the final sum in the points column.
* @return mixed * @return mixed
*/ */
...@@ -63,57 +63,57 @@ function qa_db_points_calculations() ...@@ -63,57 +63,57 @@ function qa_db_points_calculations()
return array( return array(
'qposts' => array( 'qposts' => array(
'multiple' => $options['points_multiple'] * $options['points_post_q'], 'multiple' => $options['points_multiple'] * $options['points_post_q'],
'formula' => "COUNT(*) AS qposts FROM ^posts AS userid_src WHERE userid~ AND type='Q'", 'formula' => "COUNT(*) AS qposts FROM ^posts AS userid_src WHERE userid=? AND type='Q'",
), ),
'aposts' => array( 'aposts' => array(
'multiple' => $options['points_multiple'] * $options['points_post_a'], 'multiple' => $options['points_multiple'] * $options['points_post_a'],
'formula' => "COUNT(*) AS aposts FROM ^posts AS userid_src WHERE userid~ AND type='A'", 'formula' => "COUNT(*) AS aposts FROM ^posts AS userid_src WHERE userid=? AND type='A'",
), ),
'cposts' => array( 'cposts' => array(
'multiple' => 0, 'multiple' => 0,
'formula' => "COUNT(*) AS cposts FROM ^posts AS userid_src WHERE userid~ AND type='C'", 'formula' => "COUNT(*) AS cposts FROM ^posts AS userid_src WHERE userid=? AND type='C'",
), ),
'aselects' => array( 'aselects' => array(
'multiple' => $options['points_multiple'] * $options['points_select_a'], 'multiple' => $options['points_multiple'] * $options['points_select_a'],
'formula' => "COUNT(*) AS aselects FROM ^posts AS userid_src WHERE userid~ AND type='Q' AND selchildid IS NOT NULL", 'formula' => "COUNT(*) AS aselects FROM ^posts AS userid_src WHERE userid=? AND type='Q' AND selchildid IS NOT NULL",
), ),
'aselecteds' => array( 'aselecteds' => array(
'multiple' => $options['points_multiple'] * $options['points_a_selected'], 'multiple' => $options['points_multiple'] * $options['points_a_selected'],
'formula' => "COUNT(*) AS aselecteds FROM ^posts AS userid_src JOIN ^posts AS questions ON questions.selchildid=userid_src.postid WHERE userid_src.userid~ AND userid_src.type='A' AND NOT (questions.userid<=>userid_src.userid)", 'formula' => "COUNT(*) AS aselecteds FROM ^posts AS userid_src JOIN ^posts AS questions ON questions.selchildid=userid_src.postid WHERE userid_src.userid=? AND userid_src.type='A' AND NOT (questions.userid<=>userid_src.userid)",
), ),
'qupvotes' => array( 'qupvotes' => array(
'multiple' => $options['points_multiple'] * $options['points_vote_up_q'], 'multiple' => $options['points_multiple'] * $options['points_vote_up_q'],
'formula' => "COUNT(*) AS qupvotes FROM ^uservotes AS userid_src JOIN ^posts ON userid_src.postid=^posts.postid WHERE userid_src.userid~ AND LEFT(^posts.type, 1)='Q' AND userid_src.vote>0", 'formula' => "COUNT(*) AS qupvotes FROM ^uservotes AS userid_src JOIN ^posts ON userid_src.postid=^posts.postid WHERE userid_src.userid=? AND LEFT(^posts.type, 1)='Q' AND userid_src.vote>0",
), ),
'qdownvotes' => array( 'qdownvotes' => array(
'multiple' => $options['points_multiple'] * $options['points_vote_down_q'], 'multiple' => $options['points_multiple'] * $options['points_vote_down_q'],
'formula' => "COUNT(*) AS qdownvotes FROM ^uservotes AS userid_src JOIN ^posts ON userid_src.postid=^posts.postid WHERE userid_src.userid~ AND LEFT(^posts.type, 1)='Q' AND userid_src.vote<0", 'formula' => "COUNT(*) AS qdownvotes FROM ^uservotes AS userid_src JOIN ^posts ON userid_src.postid=^posts.postid WHERE userid_src.userid=? AND LEFT(^posts.type, 1)='Q' AND userid_src.vote<0",
), ),
'aupvotes' => array( 'aupvotes' => array(
'multiple' => $options['points_multiple'] * $options['points_vote_up_a'], 'multiple' => $options['points_multiple'] * $options['points_vote_up_a'],
'formula' => "COUNT(*) AS aupvotes FROM ^uservotes AS userid_src JOIN ^posts ON userid_src.postid=^posts.postid WHERE userid_src.userid~ AND LEFT(^posts.type, 1)='A' AND userid_src.vote>0", 'formula' => "COUNT(*) AS aupvotes FROM ^uservotes AS userid_src JOIN ^posts ON userid_src.postid=^posts.postid WHERE userid_src.userid=? AND LEFT(^posts.type, 1)='A' AND userid_src.vote>0",
), ),
'adownvotes' => array( 'adownvotes' => array(
'multiple' => $options['points_multiple'] * $options['points_vote_down_a'], 'multiple' => $options['points_multiple'] * $options['points_vote_down_a'],
'formula' => "COUNT(*) AS adownvotes FROM ^uservotes AS userid_src JOIN ^posts ON userid_src.postid=^posts.postid WHERE userid_src.userid~ AND LEFT(^posts.type, 1)='A' AND userid_src.vote<0", 'formula' => "COUNT(*) AS adownvotes FROM ^uservotes AS userid_src JOIN ^posts ON userid_src.postid=^posts.postid WHERE userid_src.userid=? AND LEFT(^posts.type, 1)='A' AND userid_src.vote<0",
), ),
'cupvotes' => array( 'cupvotes' => array(
'multiple' => 0, 'multiple' => 0,
'formula' => "COUNT(*) AS cupvotes FROM ^uservotes AS userid_src JOIN ^posts ON userid_src.postid=^posts.postid WHERE userid_src.userid~ AND LEFT(^posts.type, 1)='C' AND userid_src.vote>0", 'formula' => "COUNT(*) AS cupvotes FROM ^uservotes AS userid_src JOIN ^posts ON userid_src.postid=^posts.postid WHERE userid_src.userid=? AND LEFT(^posts.type, 1)='C' AND userid_src.vote>0",
), ),
'cdownvotes' => array( 'cdownvotes' => array(
'multiple' => 0, 'multiple' => 0,
'formula' => "COUNT(*) AS cdownvotes FROM ^uservotes AS userid_src JOIN ^posts ON userid_src.postid=^posts.postid WHERE userid_src.userid~ AND LEFT(^posts.type, 1)='C' AND userid_src.vote<0", 'formula' => "COUNT(*) AS cdownvotes FROM ^uservotes AS userid_src JOIN ^posts ON userid_src.postid=^posts.postid WHERE userid_src.userid=? AND LEFT(^posts.type, 1)='C' AND userid_src.vote<0",
), ),
'qvoteds' => array( 'qvoteds' => array(
...@@ -122,7 +122,7 @@ function qa_db_points_calculations() ...@@ -122,7 +122,7 @@ function qa_db_points_calculations()
"LEAST(" . ((int)$options['points_per_q_voted_up']) . "*upvotes," . ((int)$options['points_q_voted_max_gain']) . ")" . "LEAST(" . ((int)$options['points_per_q_voted_up']) . "*upvotes," . ((int)$options['points_q_voted_max_gain']) . ")" .
"-" . "-" .
"LEAST(" . ((int)$options['points_per_q_voted_down']) . "*downvotes," . ((int)$options['points_q_voted_max_loss']) . ")" . "LEAST(" . ((int)$options['points_per_q_voted_down']) . "*downvotes," . ((int)$options['points_q_voted_max_loss']) . ")" .
"), 0) AS qvoteds FROM ^posts AS userid_src WHERE LEFT(type, 1)='Q' AND userid~", "), 0) AS qvoteds FROM ^posts AS userid_src WHERE LEFT(type, 1)='Q' AND userid=?",
), ),
'avoteds' => array( 'avoteds' => array(
...@@ -131,7 +131,7 @@ function qa_db_points_calculations() ...@@ -131,7 +131,7 @@ function qa_db_points_calculations()
"LEAST(" . ((int)$options['points_per_a_voted_up']) . "*upvotes," . ((int)$options['points_a_voted_max_gain']) . ")" . "LEAST(" . ((int)$options['points_per_a_voted_up']) . "*upvotes," . ((int)$options['points_a_voted_max_gain']) . ")" .
"-" . "-" .
"LEAST(" . ((int)$options['points_per_a_voted_down']) . "*downvotes," . ((int)$options['points_a_voted_max_loss']) . ")" . "LEAST(" . ((int)$options['points_per_a_voted_down']) . "*downvotes," . ((int)$options['points_a_voted_max_loss']) . ")" .
"), 0) AS avoteds FROM ^posts AS userid_src WHERE LEFT(type, 1)='A' AND userid~", "), 0) AS avoteds FROM ^posts AS userid_src WHERE LEFT(type, 1)='A' AND userid=?",
), ),
'cvoteds' => array( 'cvoteds' => array(
...@@ -140,17 +140,17 @@ function qa_db_points_calculations() ...@@ -140,17 +140,17 @@ function qa_db_points_calculations()
"LEAST(" . ((int)$options['points_per_c_voted_up']) . "*upvotes," . ((int)$options['points_c_voted_max_gain']) . ")" . "LEAST(" . ((int)$options['points_per_c_voted_up']) . "*upvotes," . ((int)$options['points_c_voted_max_gain']) . ")" .
"-" . "-" .
"LEAST(" . ((int)$options['points_per_c_voted_down']) . "*downvotes," . ((int)$options['points_c_voted_max_loss']) . ")" . "LEAST(" . ((int)$options['points_per_c_voted_down']) . "*downvotes," . ((int)$options['points_c_voted_max_loss']) . ")" .
"), 0) AS cvoteds FROM ^posts AS userid_src WHERE LEFT(type, 1)='C' AND userid~", "), 0) AS cvoteds FROM ^posts AS userid_src WHERE LEFT(type, 1)='C' AND userid=?",
), ),
'upvoteds' => array( 'upvoteds' => array(
'multiple' => 0, 'multiple' => 0,
'formula' => "COALESCE(SUM(upvotes), 0) AS upvoteds FROM ^posts AS userid_src WHERE userid~", 'formula' => "COALESCE(SUM(upvotes), 0) AS upvoteds FROM ^posts AS userid_src WHERE userid=?",
), ),
'downvoteds' => array( 'downvoteds' => array(
'multiple' => 0, 'multiple' => 0,
'formula' => "COALESCE(SUM(downvotes), 0) AS downvoteds FROM ^posts AS userid_src WHERE userid~", 'formula' => "COALESCE(SUM(downvotes), 0) AS downvoteds FROM ^posts AS userid_src WHERE userid=?",
), ),
); );
} }
...@@ -168,7 +168,9 @@ function qa_db_points_update_ifuser($userid, $columns) ...@@ -168,7 +168,9 @@ function qa_db_points_update_ifuser($userid, $columns)
{ {
if (qa_to_override(__FUNCTION__)) { $args=func_get_args(); return qa_call_override(__FUNCTION__, $args); } if (qa_to_override(__FUNCTION__)) { $args=func_get_args(); return qa_call_override(__FUNCTION__, $args); }
if (qa_should_update_counts() && isset($userid)) { $db = qa_service('database');
if ($db->shouldUpdateCounts() && isset($userid)) {
require_once QA_INCLUDE_DIR . 'app/options.php'; require_once QA_INCLUDE_DIR . 'app/options.php';
require_once QA_INCLUDE_DIR . 'app/cookies.php'; require_once QA_INCLUDE_DIR . 'app/cookies.php';
...@@ -185,7 +187,7 @@ function qa_db_points_update_ifuser($userid, $columns) ...@@ -185,7 +187,7 @@ function qa_db_points_update_ifuser($userid, $columns)
} }
$insertfields = 'userid, '; $insertfields = 'userid, ';
$insertvalues = '$, '; $insertvalues = '?, ';
$insertpoints = (int)qa_opt('points_base'); $insertpoints = (int)qa_opt('points_base');
$updates = ''; $updates = '';
...@@ -207,8 +209,7 @@ function qa_db_points_update_ifuser($userid, $columns) ...@@ -207,8 +209,7 @@ function qa_db_points_update_ifuser($userid, $columns)
$query = 'INSERT INTO ^userpoints (' . $insertfields . 'points) VALUES (' . $insertvalues . $insertpoints . ') ' . $query = 'INSERT INTO ^userpoints (' . $insertfields . 'points) VALUES (' . $insertvalues . $insertpoints . ') ' .
'ON DUPLICATE KEY UPDATE ' . $updates . 'points=' . $updatepoints . '+bonus'; 'ON DUPLICATE KEY UPDATE ' . $updates . 'points=' . $updatepoints . '+bonus';
// build like this so that a #, $ or ^ character in the $userid (if external integration) isn't substituted $result = $db->query($query, array($userid, $userid));
$result = qa_db_query_raw(str_replace('~', "='" . qa_db_escape_string($userid) . "'", qa_db_apply_sub($query, array($userid))));
if ($result->affectedRows() > 0) { if ($result->affectedRows() > 0) {
qa_db_userpointscount_update(); qa_db_userpointscount_update();
......
...@@ -169,18 +169,21 @@ function qa_db_user_get_handle_userids($handles) ...@@ -169,18 +169,21 @@ function qa_db_user_get_handle_userids($handles)
* @param mixed $userid * @param mixed $userid
* @param string|array $fields * @param string|array $fields
* @param string|null $value * @param string|null $value
* @throws \Q2A\Database\Exceptions\QueryException
*/ */
function qa_db_user_set($userid, $fields, $value = null) function qa_db_user_set($userid, $fields, $value = null)
{ {
if (!is_array($fields)) { if (!is_array($fields)) {
$fields = array( $fields = [$fields => $value];
$fields => $value,
);
} }
$columnRegex = '/^[A-Za-z0-9_]+$/'; // simple and secure way to ensure only valid fields are used
$sql = 'UPDATE ^users SET '; $sql = 'UPDATE ^users SET ';
foreach ($fields as $field => $fieldValue) { foreach ($fields as $field => $fieldValue) {
$sql .= qa_db_escape_string($field) . ' = ?, '; if (!preg_match($columnRegex, $field)) {
throw new \Q2A\Database\Exceptions\QueryException('Invalid field supplied to qa_db_user_set');
}
$sql .= "`$field` = ?, ";
} }
$sql = substr($sql, 0, -2) . ' WHERE userid = ?'; $sql = substr($sql, 0, -2) . ' WHERE userid = ?';
......
<?php
/*
Question2Answer by Gideon Greenspan and contributors
http://www.question2answer.org/
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
More about this license: http://www.question2answer.org/license.php
*/
namespace Q2A\Database\Exceptions;
use Q2A\Exceptions\FatalErrorException;
class QueryException extends FatalErrorException
{
/**
* QueryException constructor.
*
* @param string $message
*/
public function __construct($message = 'There was an error with the database query')
{
parent::__construct($message);
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment