From ed1d212ae2daea5e4bd043417610177093e99f19 Mon Sep 17 00:00:00 2001 From: Aleksander Machniak <alec@alec.pl> Date: Sat, 16 Jan 2016 03:03:51 -0500 Subject: [PATCH] Improved SVG cleanup code --- program/lib/Roundcube/rcube_imap_cache.php | 249 +++++++++++++++++++++++-------------------------- 1 files changed, 118 insertions(+), 131 deletions(-) diff --git a/program/lib/Roundcube/rcube_imap_cache.php b/program/lib/Roundcube/rcube_imap_cache.php index a816654..a402c18 100644 --- a/program/lib/Roundcube/rcube_imap_cache.php +++ b/program/lib/Roundcube/rcube_imap_cache.php @@ -1,6 +1,6 @@ <?php -/* +/** +-----------------------------------------------------------------------+ | This file is part of the Roundcube Webmail client | | Copyright (C) 2005-2012, The Roundcube Dev Team | @@ -99,7 +99,6 @@ ); - /** * Object constructor. * @@ -125,8 +124,12 @@ // cache all possible information by default $this->mode = self::MODE_INDEX | self::MODE_MESSAGE; - } + // database tables + $this->index_table = $db->table_name('cache_index', true); + $this->thread_table = $db->table_name('cache_thread', true); + $this->messages_table = $db->table_name('cache_messages', true); + } /** * Cleanup actions (on shutdown). @@ -137,7 +140,6 @@ $this->icache = null; } - /** * Set cache mode * @@ -147,7 +149,6 @@ { $this->mode = $mode; } - /** * Return (sorted) messages index (UIDs). @@ -171,7 +172,7 @@ // Seek in internal cache if (array_key_exists('index', $this->icache[$mailbox])) { // The index was fetched from database already, but not validated yet - if (!array_key_exists('object', $this->icache[$mailbox]['index'])) { + if (empty($this->icache[$mailbox]['index']['validated'])) { $index = $this->icache[$mailbox]['index']; } // We've got a valid index @@ -248,6 +249,7 @@ } $this->icache[$mailbox]['index'] = array( + 'validated' => true, 'object' => $data, 'sort_field' => $sort_field, 'modseq' => !empty($index['modseq']) ? $index['modseq'] : $mbox_data['HIGHESTMODSEQ'] @@ -255,7 +257,6 @@ return $data; } - /** * Return messages thread. @@ -312,7 +313,6 @@ return $index['object']; } - /** * Returns list of messages (headers). See rcube_imap::fetch_headers(). * @@ -332,11 +332,11 @@ if ($this->mode & self::MODE_MESSAGE) { // Fetch messages from cache $sql_result = $this->db->query( - "SELECT uid, data, flags" - ." FROM ".$this->db->table_name('cache_messages') - ." WHERE user_id = ?" - ." AND mailbox = ?" - ." AND uid IN (".$this->db->array2list($msgs, 'integer').")", + "SELECT `uid`, `data`, `flags`" + ." FROM {$this->messages_table}" + ." WHERE `user_id` = ?" + ." AND `mailbox` = ?" + ." AND `uid` IN (".$this->db->array2list($msgs, 'integer').")", $this->userid, $mailbox); $msgs = array_flip($msgs); @@ -375,7 +375,6 @@ return $result; } - /** * Returns message data. * @@ -399,11 +398,11 @@ if ($this->mode & self::MODE_MESSAGE) { $sql_result = $this->db->query( - "SELECT flags, data" - ." FROM ".$this->db->table_name('cache_messages') - ." WHERE user_id = ?" - ." AND mailbox = ?" - ." AND uid = ?", + "SELECT `flags`, `data`" + ." FROM {$this->messages_table}" + ." WHERE `user_id` = ?" + ." AND `mailbox` = ?" + ." AND `uid` = ?", $this->userid, $mailbox, (int)$uid); if ($sql_arr = $this->db->fetch_assoc($sql_result)) { @@ -443,7 +442,6 @@ return $message; } - /** * Saves the message in cache. * @@ -479,11 +477,11 @@ // here will work as select, assume row exist if affected_rows=0) if (!$force) { $res = $this->db->query( - "UPDATE ".$this->db->table_name('cache_messages') - ." SET flags = ?, data = ?, expires = " . ($this->ttl ? $this->db->now($this->ttl) : 'NULL') - ." WHERE user_id = ?" - ." AND mailbox = ?" - ." AND uid = ?", + "UPDATE {$this->messages_table}" + ." SET `flags` = ?, `data` = ?, `expires` = " . ($this->ttl ? $this->db->now($this->ttl) : 'NULL') + ." WHERE `user_id` = ?" + ." AND `mailbox` = ?" + ." AND `uid` = ?", $flags, $msg, $this->userid, $mailbox, (int) $message->uid); if ($this->db->affected_rows($res)) { @@ -495,8 +493,8 @@ // insert new record $res = $this->db->query( - "INSERT INTO ".$this->db->table_name('cache_messages') - ." (user_id, mailbox, uid, flags, expires, data)" + "INSERT INTO {$this->messages_table}" + ." (`user_id`, `mailbox`, `uid`, `flags`, `expires`, `data`)" ." VALUES (?, ?, ?, ?, ". ($this->ttl ? $this->db->now($this->ttl) : 'NULL') . ", ?)", $this->userid, $mailbox, (int) $message->uid, $flags, $msg); @@ -504,18 +502,17 @@ // thanks to ignore_key_errors "duplicate row" errors will be ignored if ($force && !$res && !$this->db->is_error($res)) { $this->db->query( - "UPDATE ".$this->db->table_name('cache_messages') - ." SET expires = " . ($this->ttl ? $this->db->now($this->ttl) : 'NULL') - .", flags = ?, data = ?" - ." WHERE user_id = ?" - ." AND mailbox = ?" - ." AND uid = ?", + "UPDATE {$this->messages_table}" + ." SET `expires` = " . ($this->ttl ? $this->db->now($this->ttl) : 'NULL') + .", `flags` = ?, `data` = ?" + ." WHERE `user_id` = ?" + ." AND `mailbox` = ?" + ." AND `uid` = ?", $flags, $msg, $this->userid, $mailbox, (int) $message->uid); } $this->db->set_option('ignore_key_errors', false); } - /** * Sets the flag for specified message. @@ -556,17 +553,18 @@ } } + $binary_check = $this->db->db_provider == 'oracle' ? "BITAND(`flags`, %d)" : "(`flags` & %d)"; + $this->db->query( - "UPDATE ".$this->db->table_name('cache_messages') - ." SET expires = ". ($this->ttl ? $this->db->now($this->ttl) : 'NULL') - .", flags = flags ".($enabled ? "+ $idx" : "- $idx") - ." WHERE user_id = ?" - ." AND mailbox = ?" - .(!empty($uids) ? " AND uid IN (".$this->db->array2list($uids, 'integer').")" : "") - ." AND (flags & $idx) ".($enabled ? "= 0" : "= $idx"), + "UPDATE {$this->messages_table}" + ." SET `expires` = ". ($this->ttl ? $this->db->now($this->ttl) : 'NULL') + .", `flags` = `flags` ".($enabled ? "+ $idx" : "- $idx") + ." WHERE `user_id` = ?" + ." AND `mailbox` = ?" + .(!empty($uids) ? " AND `uid` IN (".$this->db->array2list($uids, 'integer').")" : "") + ." AND " . sprintf($binary_check, $idx) . ($enabled ? " = 0" : " = $idx"), $this->userid, $mailbox); } - /** * Removes message(s) from cache. @@ -582,8 +580,8 @@ if (!strlen($mailbox)) { $this->db->query( - "DELETE FROM ".$this->db->table_name('cache_messages') - ." WHERE user_id = ?", + "DELETE FROM {$this->messages_table}" + ." WHERE `user_id` = ?", $this->userid); } else { @@ -596,14 +594,13 @@ } $this->db->query( - "DELETE FROM ".$this->db->table_name('cache_messages') - ." WHERE user_id = ?" - ." AND mailbox = ?" - .($uids !== null ? " AND uid IN (".$this->db->array2list((array)$uids, 'integer').")" : ""), + "DELETE FROM {$this->messages_table}" + ." WHERE `user_id` = ?" + ." AND `mailbox` = ?" + .($uids !== null ? " AND `uid` IN (".$this->db->array2list((array)$uids, 'integer').")" : ""), $this->userid, $mailbox); } } - /** * Clears index cache. @@ -618,18 +615,18 @@ // otherwise use 'valid' flag to not loose HIGHESTMODSEQ value if ($remove) { $this->db->query( - "DELETE FROM ".$this->db->table_name('cache_index') - ." WHERE user_id = ?" - .(strlen($mailbox) ? " AND mailbox = ".$this->db->quote($mailbox) : ""), + "DELETE FROM {$this->index_table}" + ." WHERE `user_id` = ?" + .(strlen($mailbox) ? " AND `mailbox` = ".$this->db->quote($mailbox) : ""), $this->userid ); } else { $this->db->query( - "UPDATE ".$this->db->table_name('cache_index') - ." SET valid = 0" - ." WHERE user_id = ?" - .(strlen($mailbox) ? " AND mailbox = ".$this->db->quote($mailbox) : ""), + "UPDATE {$this->index_table}" + ." SET `valid` = 0" + ." WHERE `user_id` = ?" + .(strlen($mailbox) ? " AND `mailbox` = ".$this->db->quote($mailbox) : ""), $this->userid ); } @@ -644,7 +641,6 @@ } } - /** * Clears thread cache. * @@ -653,9 +649,9 @@ function remove_thread($mailbox = null) { $this->db->query( - "DELETE FROM ".$this->db->table_name('cache_thread') - ." WHERE user_id = ?" - .(strlen($mailbox) ? " AND mailbox = ".$this->db->quote($mailbox) : ""), + "DELETE FROM {$this->thread_table}" + ." WHERE `user_id` = ?" + .(strlen($mailbox) ? " AND `mailbox` = ".$this->db->quote($mailbox) : ""), $this->userid ); @@ -668,7 +664,6 @@ $this->icache = array(); } } - /** * Clears the cache. @@ -683,7 +678,6 @@ $this->remove_message($mailbox, $uids); } - /** * Delete expired cache entries */ @@ -691,17 +685,17 @@ { $rcube = rcube::get_instance(); $db = $rcube->get_dbh(); + $now = $db->now(); - $db->query("DELETE FROM ".$db->table_name('cache_messages') - ." WHERE expires < " . $db->now()); + $db->query("DELETE FROM " . $db->table_name('cache_messages', true) + ." WHERE `expires` < $now"); - $db->query("DELETE FROM ".$db->table_name('cache_index') - ." WHERE expires < " . $db->now()); + $db->query("DELETE FROM " . $db->table_name('cache_index', true) + ." WHERE `expires` < $now"); - $db->query("DELETE FROM ".$db->table_name('cache_thread') - ." WHERE expires < " . $db->now()); + $db->query("DELETE FROM ".$db->table_name('cache_thread', true) + ." WHERE `expires` < $now"); } - /** * Fetches index data from database @@ -710,10 +704,10 @@ { // Get index from DB $sql_result = $this->db->query( - "SELECT data, valid" - ." FROM ".$this->db->table_name('cache_index') - ." WHERE user_id = ?" - ." AND mailbox = ?", + "SELECT `data`, `valid`" + ." FROM {$this->index_table}" + ." WHERE `user_id` = ?" + ." AND `mailbox` = ?", $this->userid, $mailbox); if ($sql_arr = $this->db->fetch_assoc($sql_result)) { @@ -739,7 +733,6 @@ return null; } - /** * Fetches thread data from database */ @@ -747,10 +740,10 @@ { // Get thread from DB $sql_result = $this->db->query( - "SELECT data" - ." FROM ".$this->db->table_name('cache_thread') - ." WHERE user_id = ?" - ." AND mailbox = ?", + "SELECT `data`" + ." FROM {$this->thread_table}" + ." WHERE `user_id` = ?" + ." AND `mailbox` = ?", $this->userid, $mailbox); if ($sql_arr = $this->db->fetch_assoc($sql_result)) { @@ -773,7 +766,6 @@ return null; } - /** * Saves index data into database */ @@ -788,14 +780,16 @@ (int) $mbox_data['UIDNEXT'], $modseq ? $modseq : $mbox_data['HIGHESTMODSEQ'], ); - $data = implode('@', $data); + + $data = implode('@', $data); + $expires = $this->ttl ? $this->db->now($this->ttl) : 'NULL'; if ($exists) { $res = $this->db->query( - "UPDATE ".$this->db->table_name('cache_index') - ." SET data = ?, valid = 1, expires = " . ($this->ttl ? $this->db->now($this->ttl) : 'NULL') - ." WHERE user_id = ?" - ." AND mailbox = ?", + "UPDATE {$this->index_table}" + ." SET `data` = ?, `valid` = 1, `expires` = $expires" + ." WHERE `user_id` = ?" + ." AND `mailbox` = ?", $data, $this->userid, $mailbox); if ($this->db->affected_rows($res)) { @@ -806,25 +800,24 @@ $this->db->set_option('ignore_key_errors', true); $res = $this->db->query( - "INSERT INTO ".$this->db->table_name('cache_index') - ." (user_id, mailbox, valid, expires, data)" - ." VALUES (?, ?, 1, ". ($this->ttl ? $this->db->now($this->ttl) : 'NULL') .", ?)", + "INSERT INTO {$this->index_table}" + ." (`user_id`, `mailbox`, `valid`, `expires`, `data`)" + ." VALUES (?, ?, 1, $expires, ?)", $this->userid, $mailbox, $data); // race-condition, insert failed so try update (#1489146) // thanks to ignore_key_errors "duplicate row" errors will be ignored if (!$exists && !$res && !$this->db->is_error($res)) { $res = $this->db->query( - "UPDATE ".$this->db->table_name('cache_index') - ." SET data = ?, valid = 1, expires = " . ($this->ttl ? $this->db->now($this->ttl) : 'NULL') - ." WHERE user_id = ?" - ." AND mailbox = ?", + "UPDATE {$this->index_table}" + ." SET `data` = ?, `valid` = 1, `expires` = $expires" + ." WHERE `user_id` = ?" + ." AND `mailbox` = ?", $data, $this->userid, $mailbox); } $this->db->set_option('ignore_key_errors', false); } - /** * Saves thread data into database @@ -837,16 +830,16 @@ (int) $mbox_data['UIDVALIDITY'], (int) $mbox_data['UIDNEXT'], ); - $data = implode('@', $data); - $expires = ($this->ttl ? $this->db->now($this->ttl) : 'NULL'); + $data = implode('@', $data); + $expires = $this->ttl ? $this->db->now($this->ttl) : 'NULL'; if ($exists) { $res = $this->db->query( - "UPDATE ".$this->db->table_name('cache_thread') - ." SET data = ?, expires = $expires" - ." WHERE user_id = ?" - ." AND mailbox = ?", + "UPDATE {$this->thread_table}" + ." SET `data` = ?, `expires` = $expires" + ." WHERE `user_id` = ?" + ." AND `mailbox` = ?", $data, $this->userid, $mailbox); if ($this->db->affected_rows($res)) { @@ -857,8 +850,8 @@ $this->db->set_option('ignore_key_errors', true); $res = $this->db->query( - "INSERT INTO ".$this->db->table_name('cache_thread') - ." (user_id, mailbox, expires, data)" + "INSERT INTO {$this->thread_table}" + ." (`user_id`, `mailbox`, `expires`, `data`)" ." VALUES (?, ?, $expires, ?)", $this->userid, $mailbox, $data); @@ -866,16 +859,15 @@ // thanks to ignore_key_errors "duplicate row" errors will be ignored if (!$exists && !$res && !$this->db->is_error($res)) { $this->db->query( - "UPDATE ".$this->db->table_name('cache_thread') - ." SET expires = $expires, data = ?" - ." WHERE user_id = ?" - ." AND mailbox = ?", + "UPDATE {$this->thread_table}" + ." SET `expires` = $expires, `data` = ?" + ." WHERE `user_id` = ?" + ." AND `mailbox` = ?", $data, $this->userid, $mailbox); } $this->db->set_option('ignore_key_errors', false); } - /** * Checks index/thread validity @@ -889,6 +881,8 @@ if (empty($object)) { return false; } + + $index['validated'] = true; // Get mailbox data (UIDVALIDITY, counters, etc.) for status check $mbox_data = $this->imap->folder_data($mailbox); @@ -992,14 +986,13 @@ return false; } // ... and max UID - if ($object->max() != $this->imap->id2uid($mbox_data['EXISTS'], $mailbox, true)) { + if ($object->max() != $this->imap->id2uid($mbox_data['EXISTS'], $mailbox)) { return false; } } return true; } - /** * Synchronizes the mailbox. @@ -1083,10 +1076,10 @@ // Get known UIDs if ($this->mode & self::MODE_MESSAGE) { $sql_result = $this->db->query( - "SELECT uid" - ." FROM ".$this->db->table_name('cache_messages') - ." WHERE user_id = ?" - ." AND mailbox = ?", + "SELECT `uid`" + ." FROM {$this->messages_table}" + ." WHERE `user_id` = ?" + ." AND `mailbox` = ?", $this->userid, $mailbox); while ($sql_arr = $this->db->fetch_assoc($sql_result)) { @@ -1122,12 +1115,12 @@ } $this->db->query( - "UPDATE ".$this->db->table_name('cache_messages') - ." SET flags = ?, expires = " . ($this->ttl ? $this->db->now($this->ttl) : 'NULL') - ." WHERE user_id = ?" - ." AND mailbox = ?" - ." AND uid = ?" - ." AND flags <> ?", + "UPDATE {$this->messages_table}" + ." SET `flags` = ?, `expires` = " . ($this->ttl ? $this->db->now($this->ttl) : 'NULL') + ." WHERE `user_id` = ?" + ." AND `mailbox` = ?" + ." AND `uid` = ?" + ." AND `flags` <> ?", $flags, $this->userid, $mailbox, $uid, $flags); } } @@ -1177,7 +1170,6 @@ $this->icache[$mailbox]['index']['object'] = $data; } - /** * Converts cache row into message object. * @@ -1201,7 +1193,6 @@ return $message; } - /** * Saves message stored in internal cache */ @@ -1223,7 +1214,6 @@ } } - /** * Prepares message object to be stored in database. * @@ -1232,12 +1222,14 @@ private function message_object_prepare(&$msg, &$size = 0) { // Remove body too big - if ($msg->body && ($length = strlen($msg->body))) { - $size += $length; + if (isset($msg->body)) { + $length = strlen($msg->body); - if ($size > $this->threshold * 1024) { - $size -= $length; + if ($msg->body_modified || $size + $length > $this->threshold * 1024) { unset($msg->body); + } + else { + $size += $length; } } @@ -1250,10 +1242,8 @@ unset($msg->replaces); - if (is_array($msg->structure->parts)) { - foreach ($msg->structure->parts as $part) { - $this->message_object_prepare($part, $size); - } + if (is_object($msg->structure)) { + $this->message_object_prepare($msg->structure, $size); } if (is_array($msg->parts)) { @@ -1262,7 +1252,6 @@ } } } - /** * Fetches index data from IMAP server @@ -1284,7 +1273,6 @@ return $index; } - /** * Fetches thread data from IMAP server */ @@ -1301,7 +1289,6 @@ return new rcube_result_thread($mailbox, '* THREAD'); } - } // for backward compat. -- Gitblit v1.9.1