From 474e211d5ae36b8fdff35dfccac9741f40e7e1f4 Mon Sep 17 00:00:00 2001 From: Mattias Michaux Date: Thu, 21 Apr 2016 00:44:27 +0200 Subject: [PATCH] Minimal check to validate relationship params. Conflicts: CRM/Contact/Page/AJAX.php --- CRM/Core/Page/AJAX.php | 24 ++++++++++++++++++++ CRM/Utils/Rule.php | 51 ++++++++++++++++++++++++++++++++++++++++++ CRM/Utils/Type.php | 18 +++++++++++++++ 3 files changed, 93 insertions(+) diff --git a/CRM/Core/Page/AJAX.php b/CRM/Core/Page/AJAX.php index 7d6604ea83..69c98b51f1 100644 --- a/CRM/Core/Page/AJAX.php +++ b/CRM/Core/Page/AJAX.php @@ -214,4 +214,28 @@ class CRM_Core_Page_AJAX { header("Cache-Control: max-age=$ttl, public"); } + public static function defaultSortAndPagerParams($defaultOffset = 0, $defaultRowCount = 25, $defaultSort = NULL, $defaultsortOrder = 'asc') { + $params = array(); + + $sortMapper = array(); + foreach ($_GET['columns'] as $key => $value) { + $sortMapper[$key] = CRM_Utils_Type::escape($value['data'], 'MysqlColumnName'); + }; + + $offset = isset($_GET['start']) ? CRM_Utils_Type::escape($_GET['start'], 'Integer') : $defaultOffset; + $rowCount = isset($_GET['length']) ? CRM_Utils_Type::escape($_GET['length'], 'Integer') : $defaultRowCount; + // Why is the number of order by columns limited to 1? + $sort = isset($_GET['order'][0]['column']) ? CRM_Utils_Array::value(CRM_Utils_Type::escape($_GET['order'][0]['column'], 'Integer'), $sortMapper) : $defaultSort; + $sortOrder = isset($_GET['order'][0]['dir']) ? CRM_Utils_Type::escape($_GET['order'][0]['dir'], 'MysqlOrderByDirection') : $defaultsortOrder; + + if ($sort) { + $params['sortBy'] = "`{$sort}` {$sortOrder}"; + } + + $params['page'] = ($offset / $rowCount) + 1; + $params['rp'] = $rowCount; + + return $params; + } + } diff --git a/CRM/Utils/Rule.php b/CRM/Utils/Rule.php index d2a111984b..d618255afd 100644 --- a/CRM/Utils/Rule.php +++ b/CRM/Utils/Rule.php @@ -89,6 +89,57 @@ class CRM_Utils_Rule { return TRUE; } + /** + * @param $str + * + * @return bool + */ + public static function MysqlColumnName($str) { + // check the length. + // This check can be incorrect for the . format, which can be + // a problem. + if (empty($str) || strlen($str) > 64) { + return FALSE; + } + + return TRUE; + } + + /** + * @param $str + * + * @return bool + */ + public static function MysqlColumnNameStrict($str) { + // check the length. + if (empty($str) || strlen($str) > 64) { + return FALSE; + } + + // make sure it only contains valid characters (alphanumeric and underscores) + // This check doesn't support the
. format, which can be + // a problem. + // @todo : check with the standards (http://dev.mysql.com/doc/refman/5.5/en/identifiers.html) + if (!preg_match('/^[\w_]+$/i', $str)) { + return FALSE; + } + + return TRUE; + } + + /** + * @param $str + * + * @return bool + */ + public static function MysqlOrderByDirection($str) { + if (!preg_match('/^(asc|desc)$/i', $str)) { + return FALSE; + } + + return TRUE; + } + /** * @param $str * diff --git a/CRM/Utils/Type.php b/CRM/Utils/Type.php index f5d0bc1b9e..0ce72074a6 100644 --- a/CRM/Utils/Type.php +++ b/CRM/Utils/Type.php @@ -258,6 +258,24 @@ class CRM_Utils_Type { } break; + case 'MysqlColumnName': + if (CRM_Utils_Rule::MysqlColumnName($data)) { + return str_replace('`', '', $data); + } + break; + + case 'MysqlColumnNameStrict': + if (CRM_Utils_Rule::MysqlColumnNameStrict($data)) { + return $data; + } + break; + + case 'MysqlOrderByDirection': + if (CRM_Utils_Rule::MysqlOrderByDirection($data)) { + return $data; + } + break; + default: CRM_Core_Error::fatal( $type . " is not a recognised (camel cased) data type." -- 2.25.1