From: Eileen McNaughton Date: Thu, 6 Apr 2023 23:04:07 +0000 (+1200) Subject: Fix for double escaping of custom field values X-Git-Url: https://vcs.fsf.org/?a=commitdiff_plain;h=6c3021a365a7dc2cc19e3c94eb889e8f327bd8b9;p=civicrm-core.git Fix for double escaping of custom field values --- diff --git a/CRM/Contact/BAO/Query.php b/CRM/Contact/BAO/Query.php index 86c6ae86fc..5e4a381a29 100644 --- a/CRM/Contact/BAO/Query.php +++ b/CRM/Contact/BAO/Query.php @@ -5621,12 +5621,18 @@ civicrm_relationship.start_date > {$today} * Value. * @param string $dataType * Data type of the field. + * @param bool $isAlreadyEscaped + * Ideally we would be consistent about whether we escape + * before calling this or after, but the code is a fearsome beast + * and poking the sleeping dragon could throw a cat among the + * can of worms. Hence we just schmooze this parameter in + * to prevent double escaping where it is known to occur. * * @return string * Where clause for the query. * @throws \CRM_Core_Exception */ - public static function buildClause($field, $op, $value = NULL, $dataType = NULL) { + public static function buildClause($field, $op, $value = NULL, $dataType = 'String', $isAlreadyEscaped = FALSE): string { $op = trim($op); $clause = "$field $op"; @@ -5636,12 +5642,11 @@ civicrm_relationship.start_date > {$today} return $clause; case 'IS EMPTY': - $clause = ($dataType == 'Date') ? " $field IS NULL " : " (NULLIF($field, '') IS NULL) "; + $clause = ($dataType === 'Date') ? " $field IS NULL " : " (NULLIF($field, '') IS NULL) "; return $clause; case 'IS NOT EMPTY': - $clause = ($dataType == 'Date') ? " $field IS NOT NULL " : " (NULLIF($field, '') IS NOT NULL) "; - return $clause; + return ($dataType === 'Date') ? " $field IS NOT NULL " : " (NULLIF($field, '') IS NOT NULL) "; case 'RLIKE': return " CAST({$field} AS BINARY) RLIKE BINARY '{$value}' "; @@ -5677,9 +5682,9 @@ civicrm_relationship.start_date > {$today} if ($emojiWhere === '0 = 1') { $value = $emojiWhere; } - $value = CRM_Utils_Type::escape($value, $dataType); + $value = $isAlreadyEscaped ? $value : CRM_Utils_Type::escape($value, $dataType); // if we don't have a dataType we should assume - if ($dataType == 'String' || $dataType == 'Text') { + if ($dataType === 'String' || $dataType === 'Text') { $value = "'" . $value . "'"; } return "$clause $value"; diff --git a/CRM/Core/BAO/CustomQuery.php b/CRM/Core/BAO/CustomQuery.php index 98d8d68bc0..002f5fba26 100644 --- a/CRM/Core/BAO/CustomQuery.php +++ b/CRM/Core/BAO/CustomQuery.php @@ -195,8 +195,8 @@ class CRM_Core_BAO_CustomQuery { // fix $value here to escape sql injection attacks $qillValue = NULL; if (!is_array($value)) { - $value = CRM_Core_DAO::escapeString(trim($value)); - $qillValue = CRM_Core_BAO_CustomField::displayValue($value, $id); + $escapedValue = CRM_Core_DAO::escapeString(trim($value)); + $qillValue = CRM_Core_BAO_CustomField::displayValue($escapedValue, $id); } elseif (count($value) && in_array(key($value), CRM_Core_DAO::acceptedSQLOperators(), TRUE)) { $op = key($value); @@ -273,7 +273,7 @@ class CRM_Core_BAO_CustomQuery { } else { //FIX for custom data query fired against no value(NULL/NOT NULL) - $this->_where[$grouping][] = CRM_Contact_BAO_Query::buildClause($fieldName, $op, $value, 'String'); + $this->_where[$grouping][] = CRM_Contact_BAO_Query::buildClause($fieldName, $op, $value, 'String', TRUE); } $this->_qill[$grouping][] = $field['label'] . " $qillOp $qillValue"; }