Fix bug where cache keys could exceed length limit specified in db schema (#7004)

pull/7051/head
Aleksander Machniak 5 years ago
parent 4cf8952afa
commit 4b24ba1372

@ -3,6 +3,7 @@ CHANGELOG Roundcube Webmail
- Managesieve: Fix locked UI after opening filter frame (#7007)
- Fix PHP warning: "array_merge(): Expected parameter 2 to be an array, null given in sendmail.inc (#7003)
- Fix bug where cache keys could exceed length limit specified in db schema (#7004)
RELEASE 1.4.0
-------------

@ -156,7 +156,7 @@ class rcube_cache
* @param boolean $prefix_mode Enable it to clear all keys starting
* with prefix specified in $key
*/
public function remove($key=null, $prefix_mode=false)
public function remove($key = null, $prefix_mode = false)
{
// Remove all keys
if ($key === null) {
@ -232,6 +232,33 @@ class rcube_cache
$this->cache_changes = array();
}
/**
* A helper to build cache key for specified parameters.
*
* @param string $prefix Key prefix (Max. length 64 characters)
* @param array $params Additional parameters
*
* @return string Key name
*/
public static function key_name($prefix, $params = array())
{
$cache_key = $prefix;
if (!empty($params)) {
$func = function($v) {
if (is_array($v)) {
sort($v);
}
return is_string($v) ? $v : serialize($v);
};
$params = array_map($func, $params);
$cache_key .= '.' . md5(implode(':', $params));
}
return $cache_key;
}
/**
* Reads cache entry.
*

@ -2859,14 +2859,9 @@ class rcube_imap extends rcube_storage
*
* @return array List of folders
*/
public function list_folders_subscribed($root='', $name='*', $filter=null, $rights=null, $skip_sort=false)
public function list_folders_subscribed($root = '', $name = '*', $filter = null, $rights = null, $skip_sort = false)
{
$cache_key = $root.':'.$name;
if (!empty($filter)) {
$cache_key .= ':'.(is_string($filter) ? $filter : serialize($filter));
}
$cache_key .= ':'.$rights;
$cache_key = 'mailboxes.'.md5($cache_key);
$cache_key = rcube_cache::key_name('mailboxes', array($root, $name, $filter, $rights));
// get cached folder list
$a_mboxes = $this->get_cache($cache_key);
@ -2996,14 +2991,9 @@ class rcube_imap extends rcube_storage
*
* @return array Indexed array with folder names
*/
public function list_folders($root='', $name='*', $filter=null, $rights=null, $skip_sort=false)
public function list_folders($root = '', $name = '*', $filter = null, $rights = null, $skip_sort = false)
{
$cache_key = $root.':'.$name;
if (!empty($filter)) {
$cache_key .= ':'.(is_string($filter) ? $filter : serialize($filter));
}
$cache_key .= ':'.$rights;
$cache_key = 'mailboxes.list.'.md5($cache_key);
$cache_key = rcube_cache::key_name('mailboxes.list', array($root, $name, $filter, $rights));
// get cached folder list
$a_mboxes = $this->get_cache($cache_key);
@ -3716,7 +3706,7 @@ class rcube_imap extends rcube_storage
}
// get cached metadata
$cache_key = 'mailboxes.folder-info.' . $folder;
$cache_key = rcube_cache::key_name('mailboxes.folder-info', array($folder));
$cached = $this->get_cache($cache_key);
if (is_array($cached)) {
@ -3886,7 +3876,7 @@ class rcube_imap extends rcube_storage
return false;
}
$this->clear_cache('mailboxes.folder-info.' . $folder);
$this->clear_cache(rcube_cache::key_name('mailboxes.folder-info', array($folder)));
return $this->conn->setACL($folder, $user, $acl);
}
@ -4063,13 +4053,7 @@ class rcube_imap extends rcube_storage
$entries = (array) $entries;
if (!$force) {
// create cache key
// @TODO: this is the simplest solution, but we do the same with folders list
// maybe we should store data per-entry and merge on request
sort($options);
sort($entries);
$cache_key = 'mailboxes.metadata.' . $folder;
$cache_key .= '.' . md5(serialize($options).serialize($entries));
$cache_key = rcube_cache::key_name('mailboxes.metadata', array($folder, $options, $entries));
// get cached data
$cached_data = $this->get_cache($cache_key);

@ -339,7 +339,7 @@ class rcube_ldap extends rcube_addressbook
$search_base_dn = strtr($conf['search_base_dn'], $replaces);
$search_filter = strtr($conf['search_filter'], $replaces);
$cache_key = 'DN.' . md5("$host:$search_bind_dn:$search_base_dn:$search_filter:" . $conf['search_bind_pw']);
$cache_key = rcube_cache::key_name('DN', array($host, $search_bind_dn, $search_base_dn, $search_filter, $conf['search_bind_pw']));
if ($this->cache && ($dn = $this->cache->get($cache_key))) {
$replaces['%dn'] = $dn;

Loading…
Cancel
Save