...
 
Commits (19)
...@@ -1319,6 +1319,9 @@ SELECT is_primary, ...@@ -1319,6 +1319,9 @@ SELECT is_primary,
} }
} }
if (!empty($props['country_id'])) { if (!empty($props['country_id'])) {
if (!CRM_Utils_Rule::commaSeparatedIntegers(implode(',', (array) $props['country_id']))) {
throw new CRM_Core_Exception(ts('Province limit or default country setting is incorrect'));
}
$params['condition'] = 'country_id IN (' . implode(',', (array) $props['country_id']) . ')'; $params['condition'] = 'country_id IN (' . implode(',', (array) $props['country_id']) . ')';
} }
break; break;
...@@ -1331,6 +1334,9 @@ SELECT is_primary, ...@@ -1331,6 +1334,9 @@ SELECT is_primary,
if ($context != 'get' && $context != 'validate') { if ($context != 'get' && $context != 'validate') {
$config = CRM_Core_Config::singleton(); $config = CRM_Core_Config::singleton();
if (!empty($config->countryLimit) && is_array($config->countryLimit)) { if (!empty($config->countryLimit) && is_array($config->countryLimit)) {
if (!CRM_Utils_Rule::commaSeparatedIntegers(implode(',', $config->countryLimit))) {
throw new CRM_Core_Exception(ts('Available Country setting is incorrect'));
}
$params['condition'] = 'id IN (' . implode(',', $config->countryLimit) . ')'; $params['condition'] = 'id IN (' . implode(',', $config->countryLimit) . ')';
} }
} }
...@@ -1339,6 +1345,9 @@ SELECT is_primary, ...@@ -1339,6 +1345,9 @@ SELECT is_primary,
// Filter county list based on chosen state // Filter county list based on chosen state
case 'county_id': case 'county_id':
if (!empty($props['state_province_id'])) { if (!empty($props['state_province_id'])) {
if (!CRM_Utils_Rule::commaSeparatedIntegers(implode(',', (array) $props['state_province_id']))) {
throw new CRM_Core_Exception(ts('Can only accept Integers for state_province_id filtering'));
}
$params['condition'] = 'state_province_id IN (' . implode(',', (array) $props['state_province_id']) . ')'; $params['condition'] = 'state_province_id IN (' . implode(',', (array) $props['state_province_id']) . ')';
} }
break; break;
......
...@@ -599,7 +599,7 @@ class CRM_Core_BAO_CustomField extends CRM_Core_DAO_CustomField { ...@@ -599,7 +599,7 @@ class CRM_Core_BAO_CustomField extends CRM_Core_DAO_CustomField {
if (!empty($customDataSubType)) { if (!empty($customDataSubType)) {
$subtypeClause = array(); $subtypeClause = array();
foreach ($customDataSubType as $subtype) { foreach ($customDataSubType as $subtype) {
$subtype = CRM_Core_DAO::VALUE_SEPARATOR . $subtype . CRM_Core_DAO::VALUE_SEPARATOR; $subtype = CRM_Core_DAO::VALUE_SEPARATOR . CRM_Utils_Type::escape($subtype, 'String') . CRM_Core_DAO::VALUE_SEPARATOR;
$subtypeClause[] = "$cgTable.extends_entity_column_value LIKE '%{$subtype}%'"; $subtypeClause[] = "$cgTable.extends_entity_column_value LIKE '%{$subtype}%'";
} }
if (!$onlySubType) { if (!$onlySubType) {
......
...@@ -351,6 +351,12 @@ SELECT f.id, f.label, f.data_type, ...@@ -351,6 +351,12 @@ SELECT f.id, f.label, f.data_type,
foreach ($value as $key => $val) { foreach ($value as $key => $val) {
$value[$key] = str_replace(['[', ']', ','], ['\[', '\]', '[:comma:]'], $val); $value[$key] = str_replace(['[', ']', ','], ['\[', '\]', '[:comma:]'], $val);
$value[$key] = str_replace('|', '[:separator:]', $value[$key]); $value[$key] = str_replace('|', '[:separator:]', $value[$key]);
if ($field['data_type'] == 'String') {
$value[$key] = CRM_Utils_Type::escape($value[$key], 'String');
}
elseif ($value) {
$value[$key] = CRM_Utils_Type::escape($value[$key], 'Integer');
}
} }
$value = implode(',', $value); $value = implode(',', $value);
} }
......
...@@ -68,12 +68,25 @@ class CRM_Core_Page_File extends CRM_Core_Page { ...@@ -68,12 +68,25 @@ class CRM_Core_Page_File extends CRM_Core_Page {
$mimeType = ''; $mimeType = '';
$path = CRM_Core_Config::singleton()->customFileUploadDir . $fileName; $path = CRM_Core_Config::singleton()->customFileUploadDir . $fileName;
} }
$mimeType = CRM_Utils_Request::retrieveValue('mime-type', 'String', $mimeType, FALSE);
if (!$path) { if (!$path) {
CRM_Core_Error::statusBounce('Could not retrieve the file'); CRM_Core_Error::statusBounce('Could not retrieve the file');
} }
if (empty($mimeType)) {
$passedInMimeType = self::convertBadMimeAliasTypes(CRM_Utils_Request::retrieveValue('mime-type', 'String', $mimeType, FALSE));
if (!in_array($passedInMimeType, explode(',', Civi::settings()->get('requestableMimeTypes')))) {
throw new CRM_Core_Exception("Supplied mime-type is not accepted");
}
$extension = CRM_Utils_File::getExtensionFromPath($path);
$candidateExtensions = CRM_Utils_File::getAcceptableExtensionsForMimeType($passedInMimeType);
if (!in_array($extension, $candidateExtensions)) {
throw new CRM_Core_Exception("Supplied mime-type does not match file extension");
}
// Now that we have validated mime-type supplied as much as possible lets now set the MimeType variable/
$mimeType = $passedInMimeType;
}
$buffer = file_get_contents($path); $buffer = file_get_contents($path);
if (!$buffer) { if (!$buffer) {
CRM_Core_Error::statusBounce('The file is either empty or you do not have permission to retrieve the file'); CRM_Core_Error::statusBounce('The file is either empty or you do not have permission to retrieve the file');
...@@ -101,4 +114,33 @@ class CRM_Core_Page_File extends CRM_Core_Page { ...@@ -101,4 +114,33 @@ class CRM_Core_Page_File extends CRM_Core_Page {
} }
} }
/**
* Translate one mime type to another.
*
* Certain non-standard/weird MIME types have been common. Unfortunately, because
* of the way this controller is used, the weird types may baked-into URLs.
* We clean these up for compatibility.
*
* @param string $type
* Ex: 'image/jpg'
* @return string
* Ex: 'image/jpeg'.
*/
protected static function convertBadMimeAliasTypes($type) {
$badTypes = [
// Before PNG format was ubiquitous, it was image/x-png?
'image/x-png' => 'image/png',
// People see "image/gif" and "image/png" and wrongly guess "image/jpg"?
'image/jpg' => 'image/jpeg',
'image/tif' => 'image/tiff',
'image/svg' => 'image/svg+xml',
// StackExchange attributes "pjpeg" to some quirk in an old version of IE?
'image/pjpeg' => 'image/jpeg',
];
return isset($badTypes[$type]) ? $badTypes[$type] : $type;
}
} }
...@@ -517,7 +517,8 @@ ORDER BY start_date desc ...@@ -517,7 +517,8 @@ ORDER BY start_date desc
if (is_array($value)) { if (is_array($value)) {
$type = implode(',', $value); $type = implode(',', $value);
} }
$clauses[] = "event_type_id IN ({$type})"; $clauses[] = "event_type_id IN (%2)";
$params[2] = [$type, 'String'];
} }
$eventsByDates = $this->get('eventsByDates'); $eventsByDates = $this->get('eventsByDates');
......
{* file to handle db changes in 5.13.4 during upgrade *}
...@@ -102,4 +102,24 @@ class CRM_Utils_AutoClean { ...@@ -102,4 +102,24 @@ class CRM_Utils_AutoClean {
\Civi\Core\Resolver::singleton()->call($this->callback, $this->args); \Civi\Core\Resolver::singleton()->call($this->callback, $this->args);
} }
/**
* Prohibit (de)serialization of CRM_Utils_AutoClean.
*
* The generic nature of AutoClean makes it a potential target for escalating
* serialization vulnerabilities, and there's no good reason for serializing it.
*/
public function __sleep() {
throw new \RuntimeException("CRM_Utils_AutoClean is a runtime helper. It is not intended for serialization.");
}
/**
* Prohibit (de)serialization of CRM_Utils_AutoClean.
*
* The generic nature of AutoClean makes it a potential target for escalating
* serialization vulnerabilities, and there's no good reason for deserializing it.
*/
public function __wakeup() {
throw new \RuntimeException("CRM_Utils_AutoClean is a runtime helper. It is not intended for deserialization.");
}
} }
...@@ -1066,4 +1066,29 @@ HTACCESS; ...@@ -1066,4 +1066,29 @@ HTACCESS;
return FALSE; return FALSE;
} }
/**
* Get the extensions that this MimeTpe is for
* @param string $mimeType the mime-type we want extensions for
* @return array
*/
public static function getAcceptableExtensionsForMimeType($mimeType = NULL) {
$mapping = \MimeType\Mapping::$types;
$extensions = [];
foreach ($mapping as $extension => $type) {
if ($mimeType == $type) {
$extensions[] = $extension;
}
}
return $extensions;
}
/**
* Get the extension of a file based on its path
* @param string $path path of the file to query
* @return string
*/
public static function getExtensionFromPath($path) {
return pathinfo($path, PATHINFO_EXTENSION);
}
} }
...@@ -488,6 +488,8 @@ class CRM_Utils_Rule { ...@@ -488,6 +488,8 @@ class CRM_Utils_Rule {
*/ */
public static function commaSeparatedIntegers($value) { public static function commaSeparatedIntegers($value) {
foreach (explode(',', $value) as $val) { foreach (explode(',', $value) as $val) {
// Remove any Whitespace around the key.
$val = trim($val);
if (!self::positiveInteger($val)) { if (!self::positiveInteger($val)) {
return FALSE; return FALSE;
} }
......
...@@ -432,7 +432,7 @@ function civicrm_api3_generic_getoptions($apiRequest) { ...@@ -432,7 +432,7 @@ function civicrm_api3_generic_getoptions($apiRequest) {
// Validate 'context' from params // Validate 'context' from params
$context = CRM_Utils_Array::value('context', $apiRequest['params']); $context = CRM_Utils_Array::value('context', $apiRequest['params']);
CRM_Core_DAO::buildOptionsContext($context); CRM_Core_DAO::buildOptionsContext($context);
unset($apiRequest['params']['context'], $apiRequest['params']['field']); unset($apiRequest['params']['context'], $apiRequest['params']['field'], $apiRequest['params']['condition']);
$baoName = _civicrm_api3_get_BAO($apiRequest['entity']); $baoName = _civicrm_api3_get_BAO($apiRequest['entity']);
$options = $baoName::buildOptions($fieldName, $context, $apiRequest['params']); $options = $baoName::buildOptions($fieldName, $context, $apiRequest['params']);
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
"d3-3.5.x": "d3#~3.5.17", "d3-3.5.x": "d3#~3.5.17",
"dc-2.1.x": "dc.js#~2.1.8", "dc-2.1.x": "dc.js#~2.1.8",
"crossfilter-1.3.x": "crossfilter2#~1.3.11", "crossfilter-1.3.x": "crossfilter2#~1.3.11",
"jquery": "~1.12", "jquery": "civicrm/jquery#1.12.4-civicrm-1.1",
"jquery-ui": "~1.12", "jquery-ui": "~1.12",
"lodash-compat": "~3.0", "lodash-compat": "~3.0",
"google-code-prettify": "~1.0", "google-code-prettify": "~1.0",
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
"es6-promise": "^4.2.4" "es6-promise": "^4.2.4"
}, },
"resolutions": { "resolutions": {
"angular": "~1.5.11" "angular": "~1.5.11",
"jquery": "1.12.4-civicrm-1.1"
} }
} }
...@@ -61,7 +61,8 @@ ...@@ -61,7 +61,8 @@
"psr/simple-cache": "~1.0.1", "psr/simple-cache": "~1.0.1",
"cweagans/composer-patches": "~1.0", "cweagans/composer-patches": "~1.0",
"pear/log": "1.13.1", "pear/log": "1.13.1",
"ezyang/htmlpurifier": "4.10" "ezyang/htmlpurifier": "4.10",
"katzien/php-mime-type": "2.1.0"
}, },
"scripts": { "scripts": {
"post-install-cmd": [ "post-install-cmd": [
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "93a9f686f7eb00fb9d766d262eedb09b", "content-hash": "2a06373b9174ae3aa2bfb820e2e5a35e",
"packages": [ "packages": [
{ {
"name": "civicrm/civicrm-cxn-rpc", "name": "civicrm/civicrm-cxn-rpc",
...@@ -454,6 +454,50 @@ ...@@ -454,6 +454,50 @@
], ],
"time": "2017-03-20T17:10:46+00:00" "time": "2017-03-20T17:10:46+00:00"
}, },
{
"name": "katzien/php-mime-type",
"version": "2.1.0",
"source": {
"type": "git",
"url": "https://github.com/katzien/PhpMimeType.git",
"reference": "159dfbdcd5906442f3dad89951127f0b9dfa3b78"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/katzien/PhpMimeType/zipball/159dfbdcd5906442f3dad89951127f0b9dfa3b78",
"reference": "159dfbdcd5906442f3dad89951127f0b9dfa3b78",
"shasum": ""
},
"require": {
"php": ">=5.6"
},
"require-dev": {
"phpunit/phpunit": "5.*",
"satooshi/php-coveralls": "1.*"
},
"type": "library",
"autoload": {
"psr-4": {
"MimeType\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Kat Zien"
}
],
"description": "A PHP library to detect the mime type of files.",
"homepage": "https://github.com/katzien/PhpMimeType",
"keywords": [
"mimetype",
"php"
],
"time": "2017-03-23T02:05:33+00:00"
},
{ {
"name": "marcj/topsort", "name": "marcj/topsort",
"version": "1.1.0", "version": "1.1.0",
...@@ -1980,16 +2024,16 @@ ...@@ -1980,16 +2024,16 @@
}, },
{ {
"name": "tecnickcom/tcpdf", "name": "tecnickcom/tcpdf",
"version": "6.2.13", "version": "6.2.26",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/tecnickcom/TCPDF.git", "url": "https://github.com/tecnickcom/TCPDF.git",
"reference": "95c5938aafe4b20df1454dbddb3e5005c0b26f64" "reference": "367241059ca166e3a76490f4448c284e0a161f15"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/tecnickcom/TCPDF/zipball/95c5938aafe4b20df1454dbddb3e5005c0b26f64", "url": "https://api.github.com/repos/tecnickcom/TCPDF/zipball/367241059ca166e3a76490f4448c284e0a161f15",
"reference": "95c5938aafe4b20df1454dbddb3e5005c0b26f64", "reference": "367241059ca166e3a76490f4448c284e0a161f15",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
...@@ -2018,13 +2062,13 @@ ...@@ -2018,13 +2062,13 @@
}, },
"notification-url": "https://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
"license": [ "license": [
"LGPLv3" "LGPL-3.0"
], ],
"authors": [ "authors": [
{ {
"name": "Nicola Asuni", "name": "Nicola Asuni",
"email": "info@tecnick.com", "email": "info@tecnick.com",
"homepage": "http://nicolaasuni.tecnick.com" "role": "lead"
} }
], ],
"description": "TCPDF is a PHP class for generating PDF documents and barcodes.", "description": "TCPDF is a PHP class for generating PDF documents and barcodes.",
...@@ -2038,7 +2082,7 @@ ...@@ -2038,7 +2082,7 @@
"pdf417", "pdf417",
"qrcode" "qrcode"
], ],
"time": "2017-04-26T08:14:48+00:00" "time": "2018-10-16T17:24:05+00:00"
}, },
{ {
"name": "totten/ca-config", "name": "totten/ca-config",
......
...@@ -63,14 +63,16 @@ global $installURLPath; ...@@ -63,14 +63,16 @@ global $installURLPath;
// Set the install type // Set the install type
// this is sent as a query string when the page is first loaded // this is sent as a query string when the page is first loaded
// and subsequently posted to the page as a hidden field // and subsequently posted to the page as a hidden field
if (isset($_POST['civicrm_install_type'])) { // only permit acceptable installation types to prevent issues;
$acceptableInstallTypes = ['drupal', 'wordpress', 'backdrop'];
if (isset($_POST['civicrm_install_type']) && in_array($_POST['civicrm_install_type'], $acceptableInstallTypes)) {
$installType = $_POST['civicrm_install_type']; $installType = $_POST['civicrm_install_type'];
} }
elseif (isset($_GET['civicrm_install_type'])) { elseif (isset($_GET['civicrm_install_type']) && in_array(strtolower($_GET['civicrm_install_type']), $acceptableInstallTypes)) {
$installType = strtolower($_GET['civicrm_install_type']); $installType = strtolower($_GET['civicrm_install_type']);
} }
else { else {
// default value if not set // default value if not set and not an acceptable install type.
$installType = "drupal"; $installType = "drupal";
} }
......
...@@ -14,9 +14,15 @@ Other resources for identifying changes are: ...@@ -14,9 +14,15 @@ Other resources for identifying changes are:
* https://github.com/civicrm/civicrm-joomla * https://github.com/civicrm/civicrm-joomla
* https://github.com/civicrm/civicrm-wordpress * https://github.com/civicrm/civicrm-wordpress
## CiviCRM 5.13.4
Released May 15, 2019
- **[Security advisories](release-notes/5.3.4.md#security)**
## CiviCRM 5.13.3 ## CiviCRM 5.13.3
Released May 13, 2019 Released May 14, 2019
- **[Synopsis](release-notes/5.13.3.md#synopsis)** - **[Synopsis](release-notes/5.13.3.md#synopsis)**
- **[Features](release-notes/5.13.3.md#features)** - **[Features](release-notes/5.13.3.md#features)**
......
# CiviCRM 5.13.3 # CiviCRM 5.13.3
Released May 13, 2019 Released May 14, 2019
- **[Synopsis](#synopsis)** - **[Synopsis](#synopsis)**
- **[Bugs resolved](#bugs)** - **[Bugs resolved](#bugs)**
......
# CiviCRM 5.13.4
Released May 15, 2019
- **[Security advisories](#security)**
- **[Features](#features)**
- **[Bugs resolved](#bugs)**
- **[Miscellany](#misc)**
- **[Credits](#credits)**
## <a name="security"></a>Security advisories
- **[CIVI-SA-2019-09](https://civicrm.org/advisory/civi-sa-2019-09-xxe-in-phpword)**: XXE in PHPWord
- **[CIVI-SA-2019-10](https://civicrm.org/advisory/civi-sa-2019-10-tcpdf-xss-and-rce-vulerabilities)**: TCPDF XSS and RCE vulnerabilities
- **[CIVI-SA-2019-11](https://civicrm.org/advisory/civi-sa-2019-11-jquery-objectprototype-pollution)**: jQuery Object.prototype pollution
- **[CIVI-SA-2019-12](https://civicrm.org/advisory/civi-sa-2019-12-sqli-in-country-et-al)**: SQLI in "Country", et al
- **[CIVI-SA-2019-13](https://civicrm.org/advisory/civi-sa-2019-13-harden-against-unserialize-vulnerabilities)**: Harden against unserialize vulnerabilities
- **[CIVI-SA-2019-14](https://civicrm.org/advisory/civi-sa-2019-14-sqli-in-apiv3-getoptions)**: SQLI in APIv3 GetOptions
- **[CIVI-SA-2019-15](https://civicrm.org/advisory/civi-sa-2019-15-xss-via-forged-mime-type)**: XSS via forged MIME type
- **[CIVI-SA-2019-16](https://civicrm.org/advisory/civi-sa-2019-16-sqli-in-certain-checkboxes)**: SQLI in certain checkboxes
- **[CIVI-SA-2019-17](https://civicrm.org/advisory/civi-sa-2019-17-sqli-in-manage-events)**: SQLI in "Manage Events"
- **[CIVI-SA-2019-18](https://civicrm.org/advisory/civi-sa-2019-18-xss-in-civicrm-installer)**: XSS in CiviCRM installer
- **[CIVIEXT-SA-2019-01](https://civicrm.org/advisory/civiext-sa-2019-01-multiple-security-issues-in-apiv4)**: Multiple security issues in APIv4
...@@ -1052,4 +1052,18 @@ return [ ...@@ -1052,4 +1052,18 @@ return [
'help_text' => NULL, 'help_text' => NULL,
'validate_callback' => 'CRM_Utils_Rule::color', 'validate_callback' => 'CRM_Utils_Rule::color',
], ],
'requestableMimeTypes' => [
'group_name' => 'CiviCRM Preferences',
'group' => 'core',
'name' => 'requestableMimeTypes',
'type' => 'String',
'html_type' => 'Text',
'default' => 'image/jpeg,image/pjpeg,image/gif,image/x-png,image/png,image/jpg,text/html,application/pdf',
'add' => '5.13',
'title' => ts('Mime Types that can be passed as URL params'),
'is_domain' => 1,
'is_contact' => 0,
'description' => ts('Acceptable Mime Types that can be used as part of file urls'),
'help_text' => NULL,
],
]; ];
...@@ -399,7 +399,7 @@ UNLOCK TABLES; ...@@ -399,7 +399,7 @@ UNLOCK TABLES;
LOCK TABLES `civicrm_domain` WRITE; LOCK TABLES `civicrm_domain` WRITE;
/*!40000 ALTER TABLE `civicrm_domain` DISABLE KEYS */; /*!40000 ALTER TABLE `civicrm_domain` DISABLE KEYS */;
INSERT INTO `civicrm_domain` (`id`, `name`, `description`, `config_backend`, `version`, `contact_id`, `locales`, `locale_custom_strings`) VALUES (1,'Default Domain Name',NULL,NULL,'5.13.3',1,NULL,'a:1:{s:5:\"en_US\";a:0:{}}'); INSERT INTO `civicrm_domain` (`id`, `name`, `description`, `config_backend`, `version`, `contact_id`, `locales`, `locale_custom_strings`) VALUES (1,'Default Domain Name',NULL,NULL,'5.13.4',1,NULL,'a:1:{s:5:\"en_US\";a:0:{}}');
/*!40000 ALTER TABLE `civicrm_domain` ENABLE KEYS */; /*!40000 ALTER TABLE `civicrm_domain` ENABLE KEYS */;
UNLOCK TABLES; UNLOCK TABLES;
...@@ -95,4 +95,39 @@ class CRM_Utils_FileTest extends CiviUnitTestCase { ...@@ -95,4 +95,39 @@ class CRM_Utils_FileTest extends CiviUnitTestCase {
$this->assertEquals($expectedResult, CRM_Utils_File::isValidFileName($fileName)); $this->assertEquals($expectedResult, CRM_Utils_File::isValidFileName($fileName));
} }
public function pathToFileExtension() {
$cases = [];
$cases[] = ['/evil.pdf', 'pdf'];
$cases[] = ['/helloworld.jpg', 'jpg'];
$cases[] = ['/smartwatch_1736683_1280_9af3657015e8660cc234eb1601da871.jpg', 'jpg'];
return $cases;
}
/**
* Test returning appropriate file extension
* @dataProvider pathToFileExtension
* @param string $path
* @param string $expectedExtension
*/
public function testPathToExtension($path, $expectedExtension) {
$this->assertEquals($expectedExtension, CRM_Utils_File::getExtensionFromPath($path));
}
public function mimeTypeToExtension() {
$cases = [];
$cases[] = ['text/plain', ['txt', 'text', 'conf', 'def', 'list', 'log', 'in']];
$cases[] = ['image/jpeg', ['jpeg','jpg', 'jpe']];
$cases[] = ['image/png', ['png']];
return $cases;
}
/**
* @dataProvider mimeTypeToExtension
* @param stirng $mimeType
* @param array $expectedExtensions
*/
public function testMimeTypeToExtension($mimeType, $expectedExtensions) {
$this->assertEquals($expectedExtensions, CRM_Utils_File::getAcceptableExtensionsForMimeType($mimeType));
}
} }
...@@ -479,4 +479,47 @@ class api_v3_AddressTest extends CiviUnitTestCase { ...@@ -479,4 +479,47 @@ class api_v3_AddressTest extends CiviUnitTestCase {
$this->assertEquals($expectState, $created['state_province_id']); $this->assertEquals($expectState, $created['state_province_id']);
} }
public function testBuildStateProvinceOptionsWithDodgyProvinceLimit() {
$provinceLimit = [1228, "abcd;ef"];
$this->callAPISuccess('setting', 'create', [
'provinceLimit' => $provinceLimit,
]);
$result = $this->callAPIFailure('address', 'getoptions', ['field' => 'state_province_id']);
// confirm that we hit our error not a SQLI.
$this->assertEquals('Province limit or default country setting is incorrect', $result['error_message']);
$this->callAPISuccess('setting', 'create', [
'provinceLimit' => [1228],
]);
// Now confirm with a correct province setting it works fine
$this->callAPISuccess('address', 'getoptions', ['field' => 'state_province_id']);
}
public function testBuildCountryWithDodgyCountryLimitSetting() {
$countryLimit = [1228, "abcd;ef"];
$this->callAPISuccess('setting', 'create', [
'countryLimit' => $countryLimit,
]);
$result = $this->callAPIFailure('address', 'getoptions', ['field' => 'country_id']);
// confirm that we hit our error not a SQLI.
$this->assertEquals('Available Country setting is incorrect', $result['error_message']);
$this->callAPISuccess('setting', 'create', [
'countryLimit' => [1228],
]);
// Now confirm with a correct province setting it works fine
$this->callAPISuccess('address', 'getoptions', ['field' => 'country_id']);
}
public function testBuildCountyWithDodgeStateProvinceFiltering() {
$result = $this->callAPIFailure('Address', 'getoptions', [
'field' => 'county_id',
'state_province_id' => "abcd;ef",
]);
$this->assertEquals('Can only accept Integers for state_province_id filtering', $result['error_message']);
$goodResult = $this->callAPISuccess('Address', 'getoptions', [
'field' => 'county_id',
'state_province_id' => 1004,
]);
$this->assertEquals('San Francisco', $goodResult['values'][4]);
}
} }
<?xml version="1.0" encoding="iso-8859-1" ?> <?xml version="1.0" encoding="iso-8859-1" ?>
<version> <version>
<version_no>5.13.3</version_no> <version_no>5.13.4</version_no>
</version> </version>