From f24846d5d11b3bb90420d34748530975d7868cac Mon Sep 17 00:00:00 2001 From: Seamus Lee Date: Tue, 29 Oct 2019 15:21:06 +1100 Subject: [PATCH] Implement xKerman/restricted-unserialize package to guard against unsafe unserialize --- CRM/Campaign/BAO/Query.php | 2 +- CRM/Campaign/Form/Survey/Main.php | 2 +- CRM/Campaign/Page/AJAX.php | 2 +- CRM/Contact/BAO/SavedSearch.php | 4 ++-- CRM/Contact/Page/SavedSearch.php | 2 +- .../Form/ContributionPage/Amount.php | 2 +- CRM/Core/BAO/Cache.php | 4 ++-- CRM/Core/BAO/ConfigSetting.php | 4 ++-- CRM/Core/BAO/PrevNextCache.php | 6 ++--- CRM/Core/BAO/WordReplacement.php | 4 ++-- CRM/Core/Config.php | 2 +- CRM/Core/DAO.php | 2 +- CRM/Core/Menu.php | 4 ++-- CRM/Extension/ClassLoader.php | 2 +- CRM/Member/BAO/Membership.php | 2 +- CRM/Queue/Queue/Memory.php | 4 ++-- CRM/Queue/Queue/Sql.php | 4 ++-- CRM/Queue/Runner.php | 2 +- CRM/Report/Form.php | 2 +- CRM/Utils/Array.php | 2 +- CRM/Utils/Cache/APCcache.php | 2 +- CRM/Utils/Cache/ArrayCache.php | 4 ++-- CRM/Utils/Cache/ArrayDecorator.php | 2 +- CRM/Utils/Cache/Memcache.php | 2 +- CRM/Utils/Cache/Memcached.php | 2 +- CRM/Utils/Cache/Redis.php | 2 +- CRM/Utils/Cache/SqlGroup.php | 2 +- CRM/Utils/String.php | 22 +++++++++++++++++++ Civi/Core/SettingsBag.php | 4 ++-- api/v3/SavedSearch.php | 4 ++-- 30 files changed, 63 insertions(+), 41 deletions(-) diff --git a/CRM/Campaign/BAO/Query.php b/CRM/Campaign/BAO/Query.php index d44e128009..e3841d629e 100644 --- a/CRM/Campaign/BAO/Query.php +++ b/CRM/Campaign/BAO/Query.php @@ -487,7 +487,7 @@ INNER JOIN civicrm_custom_group grp on fld.custom_group_id = grp.id $recontactInterval = CRM_Core_DAO::getFieldValue('CRM_Campaign_DAO_Survey', $surveyId, 'recontact_interval' ); - $recontactInterval = unserialize($recontactInterval); + $recontactInterval = CRM_Utils_String::unserialize($recontactInterval); if ($surveyId && is_array($recontactInterval) && !empty($recontactInterval) diff --git a/CRM/Campaign/Form/Survey/Main.php b/CRM/Campaign/Form/Survey/Main.php index 68f074ec19..b1602e3c6e 100644 --- a/CRM/Campaign/Form/Survey/Main.php +++ b/CRM/Campaign/Form/Survey/Main.php @@ -104,7 +104,7 @@ class CRM_Campaign_Form_Survey_Main extends CRM_Campaign_Form_Survey { if (!empty($defaults['result_id']) && !empty($defaults['recontact_interval'])) { $resultId = $defaults['result_id']; - $recontactInterval = unserialize($defaults['recontact_interval']); + $recontactInterval = CRM_Utils_String::unserialize($defaults['recontact_interval']); unset($defaults['recontact_interval']); $defaults['option_group_id'] = $resultId; diff --git a/CRM/Campaign/Page/AJAX.php b/CRM/Campaign/Page/AJAX.php index ecec019936..b3c0df44df 100644 --- a/CRM/Campaign/Page/AJAX.php +++ b/CRM/Campaign/Page/AJAX.php @@ -122,7 +122,7 @@ class CRM_Campaign_Page_AJAX { $survey->result_id = $id; if ($survey->find(TRUE)) { if ($survey->recontact_interval) { - $recontactInterval = unserialize($survey->recontact_interval); + $recontactInterval = CRM_Utils_String::unserialize($survey->recontact_interval); foreach ($opValues as $opValId => $opVal) { if (is_numeric($recontactInterval[$opVal['label']])) { $opValues[$opValId]['interval'] = $recontactInterval[$opVal['label']]; diff --git a/CRM/Contact/BAO/SavedSearch.php b/CRM/Contact/BAO/SavedSearch.php index bea1cf5639..b936e5022a 100644 --- a/CRM/Contact/BAO/SavedSearch.php +++ b/CRM/Contact/BAO/SavedSearch.php @@ -100,8 +100,8 @@ class CRM_Contact_BAO_SavedSearch extends CRM_Contact_DAO_SavedSearch { $fv = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_SavedSearch', $id, 'form_values'); $result = NULL; if ($fv) { - // make sure u unserialize - since it's stored in serialized form - $result = unserialize($fv); + // make sure u CRM_Utils_String::unserialize - since it's stored in serialized form + $result = CRM_Utils_String::unserialize($fv); } $specialFields = ['contact_type', 'group', 'contact_tags', 'member_membership_type_id', 'member_status_id']; diff --git a/CRM/Contact/Page/SavedSearch.php b/CRM/Contact/Page/SavedSearch.php index a101e86283..6d35a6205b 100644 --- a/CRM/Contact/Page/SavedSearch.php +++ b/CRM/Contact/Page/SavedSearch.php @@ -91,7 +91,7 @@ class CRM_Contact_Page_SavedSearch extends CRM_Core_Page { $row['description'] = $group->description; $row['id'] = $savedSearch->id; - $formValues = unserialize($savedSearch->form_values); + $formValues = CRM_Utils_String::unserialize($savedSearch->form_values); $query = new CRM_Contact_BAO_Query($formValues); $row['query_detail'] = $query->qill(); diff --git a/CRM/Contribute/Form/ContributionPage/Amount.php b/CRM/Contribute/Form/ContributionPage/Amount.php index ef3d9071c5..da176fa1ea 100644 --- a/CRM/Contribute/Form/ContributionPage/Amount.php +++ b/CRM/Contribute/Form/ContributionPage/Amount.php @@ -333,7 +333,7 @@ class CRM_Contribute_Form_ContributionPage_Amount extends CRM_Contribute_Form_Co } //CRM-16165, Don't allow reccuring contribution if membership block contain any renewable membership option - $membershipTypes = unserialize($membershipBlock->membership_types); + $membershipTypes = CRM_Utils_String::unserialize($membershipBlock->membership_types); if (!empty($fields['is_recur']) && !empty($membershipTypes)) { if (!$membershipBlock->is_separate_payment) { $errors['is_recur'] = ts('You need to enable Separate Membership Payment when online contribution page is configured for both Membership and Recurring Contribution.'); diff --git a/CRM/Core/BAO/Cache.php b/CRM/Core/BAO/Cache.php index e71e24e368..4ef618f30d 100644 --- a/CRM/Core/BAO/Cache.php +++ b/CRM/Core/BAO/Cache.php @@ -444,10 +444,10 @@ class CRM_Core_BAO_Cache extends CRM_Core_DAO_Cache { // Upgrade support -- old records (serialize) always have this punctuation, // and new records (base64) never do. if (strpos($string, ':') !== FALSE || strpos($string, ';') !== FALSE) { - return unserialize($string); + return CRM_Utils_String::unserialize($string); } else { - return unserialize(base64_decode($string)); + return CRM_Utils_String::unserialize(base64_decode($string)); } } diff --git a/CRM/Core/BAO/ConfigSetting.php b/CRM/Core/BAO/ConfigSetting.php index 8919a6d790..c30f7ae1ce 100644 --- a/CRM/Core/BAO/ConfigSetting.php +++ b/CRM/Core/BAO/ConfigSetting.php @@ -63,7 +63,7 @@ class CRM_Core_BAO_ConfigSetting { $domain->id = CRM_Core_Config::domainID(); $domain->find(TRUE); if ($domain->config_backend) { - $params = array_merge(unserialize($domain->config_backend), $params); + $params = array_merge(CRM_Utils_String::unserialize($domain->config_backend), $params); } $params = CRM_Core_BAO_ConfigSetting::filterSkipVars($params); @@ -106,7 +106,7 @@ class CRM_Core_BAO_ConfigSetting { $domain->id = CRM_Core_Config::domainID(); $domain->find(TRUE); if ($domain->config_backend) { - $defaults = unserialize($domain->config_backend); + $defaults = CRM_Utils_String::unserialize($domain->config_backend); if ($defaults === FALSE || !is_array($defaults)) { $defaults = []; return FALSE; diff --git a/CRM/Core/BAO/PrevNextCache.php b/CRM/Core/BAO/PrevNextCache.php index f217d87441..7d7cc05a7b 100644 --- a/CRM/Core/BAO/PrevNextCache.php +++ b/CRM/Core/BAO/PrevNextCache.php @@ -302,7 +302,7 @@ FROM civicrm_prevnext_cache pn $count = 0; while ($dao->fetch()) { if (self::is_serialized($dao->data)) { - $main[$count] = unserialize($dao->data); + $main[$count] = CRM_Utils_String::unserialize($dao->data); } else { $main[$count] = $dao->data; @@ -334,7 +334,7 @@ FROM civicrm_prevnext_cache pn * @return bool */ public static function is_serialized($string) { - return (@unserialize($string) !== FALSE); + return (@CRM_Utils_String::unserialize($string) !== FALSE); } /** @@ -507,7 +507,7 @@ WHERE (pn.cachekey $op %1 OR pn.cachekey $op %2) foreach ($prevNextId as $id) { $dao->id = $id; if ($dao->find(TRUE)) { - $originalData = unserialize($dao->data); + $originalData = CRM_Utils_String::unserialize($dao->data); $srcFields = ['ID', 'Name']; $swapFields = ['srcID', 'srcName', 'dstID', 'dstName']; $data = array_diff_assoc($originalData, array_fill_keys($swapFields, 1)); diff --git a/CRM/Core/BAO/WordReplacement.php b/CRM/Core/BAO/WordReplacement.php index f77891ab25..16099a1c27 100644 --- a/CRM/Core/BAO/WordReplacement.php +++ b/CRM/Core/BAO/WordReplacement.php @@ -239,7 +239,7 @@ WHERE domain_id = %1 $params["domain_id"] = $value["id"]; $params["options"] = ['wp-rebuild' => $rebuildEach]; // Unserialize word match string. - $localeCustomArray = unserialize($value["locale_custom_strings"]); + $localeCustomArray = CRM_Utils_String::unserialize($value["locale_custom_strings"]); if (!empty($localeCustomArray)) { $wordMatchArray = []; // Only return the replacement strings of the current language, @@ -315,7 +315,7 @@ WHERE domain_id = %1 1 => [$domainId, 'Integer'], ]); while ($domain->fetch()) { - return empty($domain->locale_custom_strings) ? [] : unserialize($domain->locale_custom_strings); + return empty($domain->locale_custom_strings) ? [] : CRM_Utils_String::unserialize($domain->locale_custom_strings); } } diff --git a/CRM/Core/Config.php b/CRM/Core/Config.php index f8952cf419..d63d3d9b42 100644 --- a/CRM/Core/Config.php +++ b/CRM/Core/Config.php @@ -565,7 +565,7 @@ class CRM_Core_Config extends CRM_Core_Config_MagicMerge { WHERE is_domain = 1 AND name = "installed" '); while ($dao->fetch()) { - $value = unserialize($dao->value); + $value = CRM_Utils_String::unserialize($dao->value); if (!empty($value)) { Civi::settings()->set('installed', 1); return; diff --git a/CRM/Core/DAO.php b/CRM/Core/DAO.php index b508b64e6c..c2f024face 100644 --- a/CRM/Core/DAO.php +++ b/CRM/Core/DAO.php @@ -2939,7 +2939,7 @@ SELECT contact_id return strlen($value) ? json_decode($value, TRUE) : []; case self::SERIALIZE_PHP: - return strlen($value) ? unserialize($value, ['allowed_classes' => FALSE]) : []; + return strlen($value) ? CRM_Utils_String::unserialize($value) : []; case self::SERIALIZE_COMMA: return explode(',', trim(str_replace(', ', '', $value))); diff --git a/CRM/Core/Menu.php b/CRM/Core/Menu.php index c6fefdc91a..6f19e4a573 100644 --- a/CRM/Core/Menu.php +++ b/CRM/Core/Menu.php @@ -609,13 +609,13 @@ UNION ( // Move module_data into main item. if (isset(self::$_menuCache[$menu->path]['module_data'])) { CRM_Utils_Array::extend(self::$_menuCache[$menu->path], - unserialize(self::$_menuCache[$menu->path]['module_data'])); + CRM_Utils_String::unserialize(self::$_menuCache[$menu->path]['module_data'])); unset(self::$_menuCache[$menu->path]['module_data']); } // Unserialize other elements. foreach (self::$_serializedElements as $element) { - self::$_menuCache[$menu->path][$element] = unserialize($menu->$element); + self::$_menuCache[$menu->path][$element] = CRM_Utils_String::unserialize($menu->$element); if (strpos($path, $menu->path) !== FALSE) { $menuPath = &self::$_menuCache[$menu->path]; diff --git a/CRM/Extension/ClassLoader.php b/CRM/Extension/ClassLoader.php index 4569f6c2e4..d0845911e0 100644 --- a/CRM/Extension/ClassLoader.php +++ b/CRM/Extension/ClassLoader.php @@ -89,7 +89,7 @@ class CRM_Extension_ClassLoader { $loader = $this->buildClassLoader(); $ser = serialize($loader); file_put_contents($file, - sprintf("register(); diff --git a/CRM/Member/BAO/Membership.php b/CRM/Member/BAO/Membership.php index 9ab78c4ad2..feaa35fef1 100644 --- a/CRM/Member/BAO/Membership.php +++ b/CRM/Member/BAO/Membership.php @@ -754,7 +754,7 @@ INNER JOIN civicrm_membership_type type ON ( type.id = membership.membership_ty if ($dao->find(TRUE)) { CRM_Core_DAO::storeValues($dao, $membershipBlock); if (!empty($membershipBlock['membership_types'])) { - $membershipTypes = unserialize($membershipBlock['membership_types']); + $membershipTypes = CRM_Utils_String::unserialize($membershipBlock['membership_types']); if (!is_array($membershipTypes)) { return $membershipBlock; } diff --git a/CRM/Queue/Queue/Memory.php b/CRM/Queue/Queue/Memory.php index 0c840c1c36..99b92959ee 100644 --- a/CRM/Queue/Queue/Memory.php +++ b/CRM/Queue/Queue/Memory.php @@ -137,7 +137,7 @@ class CRM_Queue_Queue_Memory extends CRM_Queue_Queue { $item = new stdClass(); $item->id = $id; - $item->data = unserialize($data); + $item->data = CRM_Utils_String::unserialize($data); return $item; } else { @@ -166,7 +166,7 @@ class CRM_Queue_Queue_Memory extends CRM_Queue_Queue { $item = new stdClass(); $item->id = $id; - $item->data = unserialize($data); + $item->data = CRM_Utils_String::unserialize($data); return $item; } // nothing in queue diff --git a/CRM/Queue/Queue/Sql.php b/CRM/Queue/Queue/Sql.php index 28f13506de..dc9474c1a1 100644 --- a/CRM/Queue/Queue/Sql.php +++ b/CRM/Queue/Queue/Sql.php @@ -160,7 +160,7 @@ class CRM_Queue_Queue_Sql extends CRM_Queue_Queue { # $dao->submit_time = date('YmdHis', strtotime($dao->submit_time)); # $dao->release_time = date('YmdHis', $nowEpoch + $lease_time); # $dao->save(); - $dao->data = unserialize($dao->data); + $dao->data = CRM_Utils_String::unserialize($dao->data); $result = $dao; } @@ -196,7 +196,7 @@ class CRM_Queue_Queue_Sql extends CRM_Queue_Queue { '1' => [date('YmdHis', $nowEpoch + $lease_time), 'String'], '2' => [$dao->id, 'Integer'], ]); - $dao->data = unserialize($dao->data); + $dao->data = CRM_Utils_String::unserialize($dao->data); return $dao; } } diff --git a/CRM/Queue/Runner.php b/CRM/Queue/Runner.php index fa2817e713..48906b6abb 100644 --- a/CRM/Queue/Runner.php +++ b/CRM/Queue/Runner.php @@ -85,7 +85,7 @@ class CRM_Queue_Runner { */ public static function instance($qrid) { if (!empty($_SESSION['queueRunners'][$qrid])) { - return unserialize($_SESSION['queueRunners'][$qrid]); + return CRM_Utils_String::unserialize($_SESSION['queueRunners'][$qrid]); } else { return NULL; diff --git a/CRM/Report/Form.php b/CRM/Report/Form.php index 783026daa2..918e24c997 100644 --- a/CRM/Report/Form.php +++ b/CRM/Report/Form.php @@ -632,7 +632,7 @@ class CRM_Report_Form extends CRM_Core_Form { $formValues = CRM_Utils_Array::value('form_values', $this->_instanceValues); if ($formValues) { - $this->_formValues = unserialize($formValues); + $this->_formValues = CRM_Utils_String::unserialize($formValues); } else { $this->_formValues = NULL; diff --git a/CRM/Utils/Array.php b/CRM/Utils/Array.php index 7dd32cd4be..b28f677703 100644 --- a/CRM/Utils/Array.php +++ b/CRM/Utils/Array.php @@ -499,7 +499,7 @@ class CRM_Utils_Array { * The input array with duplicate values removed. */ public static function crmArrayUnique($array) { - $result = array_map("unserialize", array_unique(array_map("serialize", $array))); + $result = array_map("CRM_Utils_String::unserialize", array_unique(array_map("serialize", $array))); foreach ($result as $key => $value) { if (is_array($value)) { $result[$key] = self::crmArrayUnique($value); diff --git a/CRM/Utils/Cache/APCcache.php b/CRM/Utils/Cache/APCcache.php index 187da7edb8..80c3ac6a2b 100644 --- a/CRM/Utils/Cache/APCcache.php +++ b/CRM/Utils/Cache/APCcache.php @@ -145,7 +145,7 @@ class CRM_Utils_Cache_APCcache implements CRM_Utils_Cache_Interface { } private function reobjectify($value) { - return is_object($value) ? unserialize(serialize($value)) : $value; + return is_object($value) ? CRM_Utils_String::unserialize(serialize($value)) : $value; } } diff --git a/CRM/Utils/Cache/ArrayCache.php b/CRM/Utils/Cache/ArrayCache.php index c83f3f1f4e..de44d73b64 100644 --- a/CRM/Utils/Cache/ArrayCache.php +++ b/CRM/Utils/Cache/ArrayCache.php @@ -121,12 +121,12 @@ class CRM_Utils_Cache_ArrayCache implements CRM_Utils_Cache_Interface { private function reobjectify($value) { if (is_object($value)) { - return unserialize(serialize($value)); + return CRM_Utils_String::unserialize(serialize($value)); } if (is_array($value)) { foreach ($value as $p) { if (is_object($p)) { - return unserialize(serialize($value)); + return CRM_Utils_String::unserialize(serialize($value)); } } } diff --git a/CRM/Utils/Cache/ArrayDecorator.php b/CRM/Utils/Cache/ArrayDecorator.php index 86ac79728a..0f75d84a1a 100644 --- a/CRM/Utils/Cache/ArrayDecorator.php +++ b/CRM/Utils/Cache/ArrayDecorator.php @@ -137,7 +137,7 @@ class CRM_Utils_Cache_ArrayDecorator implements CRM_Utils_Cache_Interface { } private function reobjectify($value) { - return is_object($value) ? unserialize(serialize($value)) : $value; + return is_object($value) ? CRM_Utils_String::unserialize(serialize($value)) : $value; } } diff --git a/CRM/Utils/Cache/Memcache.php b/CRM/Utils/Cache/Memcache.php index 511663792e..64db5ae9f1 100644 --- a/CRM/Utils/Cache/Memcache.php +++ b/CRM/Utils/Cache/Memcache.php @@ -149,7 +149,7 @@ class CRM_Utils_Cache_Memcache implements CRM_Utils_Cache_Interface { public function get($key, $default = NULL) { CRM_Utils_Cache::assertValidKey($key); $result = $this->_cache->get($this->getTruePrefix() . $key); - return ($result === FALSE) ? $default : unserialize($result); + return ($result === FALSE) ? $default : CRM_Utils_String::unserialize($result); } /** diff --git a/CRM/Utils/Cache/Memcached.php b/CRM/Utils/Cache/Memcached.php index fd3aee39c2..6e2a1332a5 100644 --- a/CRM/Utils/Cache/Memcached.php +++ b/CRM/Utils/Cache/Memcached.php @@ -167,7 +167,7 @@ class CRM_Utils_Cache_Memcached implements CRM_Utils_Cache_Interface { $result = $this->_cache->get($key); switch ($this->_cache->getResultCode()) { case Memcached::RES_SUCCESS: - return unserialize($result); + return CRM_Utils_String::unserialize($result); case Memcached::RES_NOTFOUND: return $default; diff --git a/CRM/Utils/Cache/Redis.php b/CRM/Utils/Cache/Redis.php index f7c8435f79..b3b01fee25 100644 --- a/CRM/Utils/Cache/Redis.php +++ b/CRM/Utils/Cache/Redis.php @@ -153,7 +153,7 @@ class CRM_Utils_Cache_Redis implements CRM_Utils_Cache_Interface { public function get($key, $default = NULL) { CRM_Utils_Cache::assertValidKey($key); $result = $this->_cache->get($this->_prefix . $key); - return ($result === FALSE) ? $default : unserialize($result); + return ($result === FALSE) ? $default : CRM_Utils_String::unserialize($result); } /** diff --git a/CRM/Utils/Cache/SqlGroup.php b/CRM/Utils/Cache/SqlGroup.php index 840886c65e..b206c1b04c 100644 --- a/CRM/Utils/Cache/SqlGroup.php +++ b/CRM/Utils/Cache/SqlGroup.php @@ -184,7 +184,7 @@ class CRM_Utils_Cache_SqlGroup implements CRM_Utils_Cache_Interface { } private function reobjectify($value) { - return is_object($value) ? unserialize(serialize($value)) : $value; + return is_object($value) ? CRM_Utils_String::unserialize(serialize($value)) : $value; } /** diff --git a/CRM/Utils/String.php b/CRM/Utils/String.php index d0f295dd18..44c4153368 100644 --- a/CRM/Utils/String.php +++ b/CRM/Utils/String.php @@ -31,6 +31,9 @@ * @copyright CiviCRM LLC (c) 2004-2019 */ +use function xKerman\Restricted\unserialize; +use xKerman\Restricted\UnserializeFailedException; + require_once 'HTML/QuickForm/Rule/Email.php'; /** @@ -936,4 +939,23 @@ class CRM_Utils_String { return array_values(array_unique($result)); } + /** + * Use xkerman/restricted-unserialize to unserialize a string of data. + * @param string|NULL $string + * + * @return mixed + * @throws CRM_Core_Exception + */ + public static function unserialize($string) { + if (!is_string($string)) { + return FALSE; + } + try { + return unserialize($string); + } + catch (UnserializeFailedException $e) { + throw new CRM_Core_Exception($e->getMessage()); + } + } + } diff --git a/Civi/Core/SettingsBag.php b/Civi/Core/SettingsBag.php index 4155e7baf8..bd419c0fca 100644 --- a/Civi/Core/SettingsBag.php +++ b/Civi/Core/SettingsBag.php @@ -150,7 +150,7 @@ class SettingsBag { if (!$isUpgradeMode || \CRM_Core_DAO::checkTableExists('civicrm_setting')) { $dao = \CRM_Core_DAO::executeQuery($this->createQuery()->toSQL()); while ($dao->fetch()) { - $this->values[$dao->name] = ($dao->value !== NULL) ? unserialize($dao->value) : NULL; + $this->values[$dao->name] = ($dao->value !== NULL) ? \CRM_Utils_String::unserialize($dao->value) : NULL; } } @@ -355,7 +355,7 @@ class SettingsBag { foreach ($metadata['on_change'] as $callback) { call_user_func( \Civi\Core\Resolver::singleton()->get($callback), - unserialize($dao->value), + \CRM_Utils_String::unserialize($dao->value), $value, $metadata, $this->domainId diff --git a/api/v3/SavedSearch.php b/api/v3/SavedSearch.php index c515e890e2..a379b7f4a4 100644 --- a/api/v3/SavedSearch.php +++ b/api/v3/SavedSearch.php @@ -57,7 +57,7 @@ function civicrm_api3_saved_search_create($params) { } else { // Assume that form_values is serialized. - $params["formValues"] = unserialize($params["form_values"]); + $params["formValues"] = CRM_Utils_String::unserialize($params["form_values"]); } } @@ -109,7 +109,7 @@ function _civicrm_api3_saved_search_result_cleanup(&$result) { // Only clean up the values if there are values. (A getCount operation // for example does not return values.) foreach ($result['values'] as $key => $value) { - $result['values'][$key]['form_values'] = unserialize($value['form_values']); + $result['values'][$key]['form_values'] = CRM_Utils_String::unserialize($value['form_values']); } } } -- 2.25.1