Fix kolab cache issues with malformed/unsupported character sequences

being stored in data, xml and words columns, which caused malformed
(and inaccessible) objects (Bug #1912, #2662)
This commit is contained in:
Aleksander Machniak 2013-12-12 09:45:18 +01:00
parent 94339e0e4b
commit a7c4ebf15d
3 changed files with 44 additions and 14 deletions

View file

@ -30,7 +30,7 @@ CREATE TABLE `kolab_cache_contact` (
`created` DATETIME DEFAULT NULL,
`changed` DATETIME DEFAULT NULL,
`data` TEXT NOT NULL,
`xml` LONGTEXT NOT NULL,
`xml` LONGBLOB NOT NULL,
`tags` VARCHAR(255) NOT NULL,
`words` TEXT NOT NULL,
`type` VARCHAR(32) CHARACTER SET ascii NOT NULL,
@ -49,7 +49,7 @@ CREATE TABLE `kolab_cache_event` (
`created` DATETIME DEFAULT NULL,
`changed` DATETIME DEFAULT NULL,
`data` TEXT NOT NULL,
`xml` TEXT NOT NULL,
`xml` LONGBLOB NOT NULL,
`tags` VARCHAR(255) NOT NULL,
`words` TEXT NOT NULL,
`dtstart` DATETIME,
@ -68,7 +68,7 @@ CREATE TABLE `kolab_cache_task` (
`created` DATETIME DEFAULT NULL,
`changed` DATETIME DEFAULT NULL,
`data` TEXT NOT NULL,
`xml` TEXT NOT NULL,
`xml` LONGBLOB NOT NULL,
`tags` VARCHAR(255) NOT NULL,
`words` TEXT NOT NULL,
`dtstart` DATETIME,
@ -87,7 +87,7 @@ CREATE TABLE `kolab_cache_journal` (
`created` DATETIME DEFAULT NULL,
`changed` DATETIME DEFAULT NULL,
`data` TEXT NOT NULL,
`xml` TEXT NOT NULL,
`xml` LONGBLOB NOT NULL,
`tags` VARCHAR(255) NOT NULL,
`words` TEXT NOT NULL,
`dtstart` DATETIME,
@ -106,7 +106,7 @@ CREATE TABLE `kolab_cache_note` (
`created` DATETIME DEFAULT NULL,
`changed` DATETIME DEFAULT NULL,
`data` TEXT NOT NULL,
`xml` TEXT NOT NULL,
`xml` LONGBLOB NOT NULL,
`tags` VARCHAR(255) NOT NULL,
`words` TEXT NOT NULL,
CONSTRAINT `fk_kolab_cache_note_folder` FOREIGN KEY (`folder_id`)
@ -123,7 +123,7 @@ CREATE TABLE `kolab_cache_file` (
`created` DATETIME DEFAULT NULL,
`changed` DATETIME DEFAULT NULL,
`data` TEXT NOT NULL,
`xml` TEXT NOT NULL,
`xml` LONGBLOB NOT NULL,
`tags` VARCHAR(255) NOT NULL,
`words` TEXT NOT NULL,
`filename` varchar(255) DEFAULT NULL,
@ -142,7 +142,7 @@ CREATE TABLE `kolab_cache_configuration` (
`created` DATETIME DEFAULT NULL,
`changed` DATETIME DEFAULT NULL,
`data` TEXT NOT NULL,
`xml` TEXT NOT NULL,
`xml` LONGBLOB NOT NULL,
`tags` VARCHAR(255) NOT NULL,
`words` TEXT NOT NULL,
`type` VARCHAR(32) CHARACTER SET ascii NOT NULL,
@ -161,7 +161,7 @@ CREATE TABLE `kolab_cache_freebusy` (
`created` DATETIME DEFAULT NULL,
`changed` DATETIME DEFAULT NULL,
`data` TEXT NOT NULL,
`xml` TEXT NOT NULL,
`xml` LONGBLOB NOT NULL,
`tags` VARCHAR(255) NOT NULL,
`words` TEXT NOT NULL,
`dtstart` DATETIME,
@ -172,4 +172,4 @@ CREATE TABLE `kolab_cache_freebusy` (
) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;
INSERT INTO `system` (`name`, `value`) VALUES ('libkolab-version', '2013110400');
INSERT INTO `system` (`name`, `value`) VALUES ('libkolab-version', '2013121100');

View file

@ -0,0 +1,13 @@
-- well, these deletes are really optional
-- we can clear all caches or only contacts/events/tasks
-- the issue we're fixing here was about contacts (Bug #2662)
DELETE FROM `kolab_folders` WHERE `type` IN ('contact', 'event', 'task');
ALTER TABLE `kolab_cache_contact` CHANGE `xml` `xml` LONGBLOB NOT NULL;
ALTER TABLE `kolab_cache_event` CHANGE `xml` `xml` LONGBLOB NOT NULL;
ALTER TABLE `kolab_cache_task` CHANGE `xml` `xml` LONGBLOB NOT NULL;
ALTER TABLE `kolab_cache_journal` CHANGE `xml` `xml` LONGBLOB NOT NULL;
ALTER TABLE `kolab_cache_note` CHANGE `xml` `xml` LONGBLOB NOT NULL;
ALTER TABLE `kolab_cache_file` CHANGE `xml` `xml` LONGBLOB NOT NULL;
ALTER TABLE `kolab_cache_configuration` CHANGE `xml` `xml` LONGBLOB NOT NULL;
ALTER TABLE `kolab_cache_freebusy` CHANGE `xml` `xml` LONGBLOB NOT NULL;

View file

@ -661,7 +661,9 @@ class kolab_storage_cache
}
}
$sql_data['data'] = serialize($data);
// use base64 encoding (Bug #1912, #2662)
$sql_data['data'] = base64_encode(serialize($data));
return $sql_data;
}
@ -670,8 +672,23 @@ class kolab_storage_cache
*/
protected function _unserialize($sql_arr)
{
// check if data is a base64-encoded string, for backward compat.
if (strpos(substr($sql_arr['data'], 0, 64), ':') === false) {
$sql_arr['data'] = base64_decode($sql_arr['data']);
}
$object = unserialize($sql_arr['data']);
// de-serialization failed
if ($object === false) {
rcube::raise_error(array(
'code' => 900, 'type' => 'php',
'message' => "Malformed data for {$this->resource_uri}/{$sql_arr['msguid']} object."
), true);
return null;
}
// decode binary properties
foreach ($this->binary_items as $key => $regexp) {
if (!empty($object[$key]) && preg_match($regexp, $sql_arr['xml'], $m)) {
@ -680,10 +697,10 @@ class kolab_storage_cache
}
// add meta data
$object['_type'] = $sql_arr['type'] ?: $this->folder->type;
$object['_msguid'] = $sql_arr['msguid'];
$object['_mailbox'] = $this->folder->name;
$object['_size'] = strlen($sql_arr['xml']);
$object['_type'] = $sql_arr['type'] ?: $this->folder->type;
$object['_msguid'] = $sql_arr['msguid'];
$object['_mailbox'] = $this->folder->name;
$object['_size'] = strlen($sql_arr['xml']);
$object['_formatobj'] = kolab_format::factory($object['_type'], 3.0, $sql_arr['xml']);
return $object;