From 2b7b1113d48a608468368dd2c17fb49b118a6c77 Mon Sep 17 00:00:00 2001 From: Seamus Lee Date: Wed, 4 Mar 2020 07:48:35 +1100 Subject: [PATCH] [MOSS] CIV-01-020 Validate value in the query building logic for privacy flag fields --- CRM/Contact/BAO/Query.php | 9 +++++++- tests/phpunit/api/v3/ContactTest.php | 32 ++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/CRM/Contact/BAO/Query.php b/CRM/Contact/BAO/Query.php index 04e33776d1..4ccb455f21 100644 --- a/CRM/Contact/BAO/Query.php +++ b/CRM/Contact/BAO/Query.php @@ -3092,7 +3092,7 @@ class CRM_Contact_BAO_Query { $groupContactCacheClause = $this->addGroupContactCache($smartGroupIDs, $gccTableAlias, "contact_a", $op); if (!empty($groupContactCacheClause)) { if ($isNotOp) { - $groupIds = implode(',', (array) $smartGroupIDs); + $groupIds = CRM_Utils_Type::validate(implode(',', (array) $smartGroupIDs), 'CommaSeparatedIntegers'); $gcTable = "civicrm_group_contact_{$this->_groupUniqueKey}"; $joinClause = ["contact_a.id = {$gcTable}.contact_id"]; $this->_tables[$gcTable] = $this->_whereTables[$gcTable] = " LEFT JOIN civicrm_group_contact {$gcTable} ON (" . implode(' AND ', $joinClause) . ")"; @@ -4050,12 +4050,19 @@ WHERE $smartGroupClause public function privacy(&$values) { list($name, $op, $value, $grouping) = $values; //fixed for profile search listing CRM-4633 + if (is_array($value)) { + if (in_array(key($value), CRM_Core_DAO::acceptedSQLOperators(), TRUE)) { + $op = key($value); + $value = $value[$op]; + } + } if (strpbrk($value, "[")) { $value = "'{$value}'"; $op = "!{$op}"; $this->_where[$grouping][] = "contact_a.{$name} $op $value"; } else { + CRM_Utils_Type::validate($value, 'Integer'); $this->_where[$grouping][] = "contact_a.{$name} $op $value"; } $field = CRM_Utils_Array::value($name, $this->_fields); diff --git a/tests/phpunit/api/v3/ContactTest.php b/tests/phpunit/api/v3/ContactTest.php index e81df03a6f..99f28541e3 100644 --- a/tests/phpunit/api/v3/ContactTest.php +++ b/tests/phpunit/api/v3/ContactTest.php @@ -4571,4 +4571,36 @@ class api_v3_ContactTest extends CiviUnitTestCase { return [$contact1, $contact2]; } + public function versionAndPrivacyOption() { + $version = [3, 4]; + $fields = ['do_not_mail', 'do_not_email', 'do_not_sms', 'is_opt_out', 'do_not_trade']; + $tests = []; + foreach ($fields as $field) { + foreach ($version as $v) { + $tests[] = [$v, 1, $field, 1]; + $tests[] = [$v, 0, $field, 3]; + $tests[] = [$v, ['!=' => 1], $field, 3]; + $tests[] = [$v, ['!=' => 0], $field, 1]; + } + } + return $tests; + } + + /** + * CRM-14743 - test api respects search operators. + * + * @param int $version + * + * @dataProvider versionAndPrivacyOption + */ + public function testGetContactsByPrivacyFlag($version, $query, $field, $expected) { + $this->_apiversion = $version; + $contact1 = $this->individualCreate(); + $contact2 = $this->individualCreate([$field => 1]); + $contact = $this->callAPISuccess('Contact', 'get', [$field => $query]); + $this->assertEquals($expected, $contact['count']); + $this->callAPISuccess('Contact', 'delete', ['id' => $contact1, 'skip_undelete' => 1]); + $this->callAPISuccess('Contact', 'delete', ['id' => $contact2, 'skip_undelete' => 1]); + } + } -- 2.25.1