From 34a0902089a410d1f7dda78d1f8b0771333c09df Mon Sep 17 00:00:00 2001
From: Aleksander Machniak <alec@alec.pl>
Date: Fri, 12 Sep 2014 08:37:51 -0400
Subject: [PATCH] Use consistent column/table quoting in sql queries

---
 bin/indexcontacts.sh                                    |    2 
 program/lib/Roundcube/rcube_cache_shared.php            |   40 +-
 program/lib/Roundcube/rcube_session.php                 |   30 +-
 program/lib/Roundcube/rcube_contacts.php                |  160 ++++++------
 bin/deluser.sh                                          |    2 
 program/lib/Roundcube/rcube_spellchecker.php            |   25 -
 bin/cleandb.sh                                          |   12 
 bin/moduserprefs.sh                                     |    4 
 installer/test.php                                      |   10 
 tests/Framework/ImapCache.php                           |    2 
 program/lib/Roundcube/rcube_cache.php                   |   51 +--
 program/lib/Roundcube/rcube_db.php                      |   74 +++++
 program/lib/Roundcube/rcube_user.php                    |  103 +++----
 bin/updatedb.sh                                         |   15 
 plugins/squirrelmail_usercopy/squirrelmail_usercopy.php |    7 
 program/steps/utils/killcache.inc                       |   13 
 program/lib/Roundcube/rcube_imap_cache.php              |  196 +++++++-------
 17 files changed, 406 insertions(+), 340 deletions(-)

diff --git a/bin/cleandb.sh b/bin/cleandb.sh
index 165d33f..9edfeec 100755
--- a/bin/cleandb.sh
+++ b/bin/cleandb.sh
@@ -48,7 +48,7 @@
 
 foreach (array('contacts','contactgroups','identities') as $table) {
 
-    $sqltable = $db->table_name($table);
+    $sqltable = $db->table_name($table, true);
 
     // also delete linked records
     // could be skipped for databases which respect foreign key constraints
@@ -59,10 +59,10 @@
         $memberstable = $db->table_name('contactgroupmembers');
 
         $db->query(
-            "DELETE FROM $memberstable".
-            " WHERE $pk IN (".
-                "SELECT $pk FROM $sqltable".
-                " WHERE del=1 AND changed < ?".
+            "DELETE FROM " . $db->quote_identifier($memberstable).
+            " WHERE `$pk` IN (".
+                "SELECT `$pk` FROM $sqltable".
+                " WHERE `del` = 1 AND `changed` < ?".
             ")",
             $threshold);
 
@@ -70,7 +70,7 @@
     }
 
     // delete outdated records
-    $db->query("DELETE FROM $sqltable WHERE del=1 AND changed < ?", $threshold);
+    $db->query("DELETE FROM $sqltable WHERE `del` = 1 AND `changed` < ?", $threshold);
 
     echo $db->affected_rows() . " records deleted from '$table'\n";
 }
diff --git a/bin/deluser.sh b/bin/deluser.sh
index f12ec90..9504d5b 100755
--- a/bin/deluser.sh
+++ b/bin/deluser.sh
@@ -91,7 +91,7 @@
 // deleting the user record should be sufficient due to ON DELETE CASCADE foreign key references
 // but not all database backends actually support this so let's do it by hand
 foreach (array('identities','contacts','contactgroups','dictionaries','cache','cache_index','cache_messages','cache_thread','searches','users') as $table) {
-    $db->query('DELETE FROM ' . $db->table_name($table) . ' WHERE user_id=?', $user->ID);
+    $db->query('DELETE FROM ' . $db->table_name($table, true) . ' WHERE `user_id` = ?', $user->ID);
 }
 
 if ($db->is_error()) {
diff --git a/bin/indexcontacts.sh b/bin/indexcontacts.sh
index df40380..9509dc0 100755
--- a/bin/indexcontacts.sh
+++ b/bin/indexcontacts.sh
@@ -35,7 +35,7 @@
 }
 
 // iterate over all users
-$sql_result = $db->query("SELECT user_id FROM " . $db->table_name('users') . " ORDER BY user_id");
+$sql_result = $db->query("SELECT `user_id` FROM " . $db->table_name('users', true) . " ORDER BY `user_id`");
 while ($sql_result && ($sql_arr = $db->fetch_assoc($sql_result))) {
     echo "Indexing contacts for user " . $sql_arr['user_id'] . "...";
 
diff --git a/bin/moduserprefs.sh b/bin/moduserprefs.sh
index 8a9725f..e892b1f 100755
--- a/bin/moduserprefs.sh
+++ b/bin/moduserprefs.sh
@@ -58,10 +58,10 @@
 $query = '1=1';
 
 if ($args['user'])
-	$query = 'user_id=' . intval($args['user']);
+	$query = '`user_id` = ' . intval($args['user']);
 
 // iterate over all users
-$sql_result = $db->query("SELECT * FROM " . $db->table_name('users') . " WHERE $query");
+$sql_result = $db->query("SELECT * FROM " . $db->table_name('users', true) . " WHERE $query");
 while ($sql_result && ($sql_arr = $db->fetch_assoc($sql_result))) {
 	echo "Updating prefs for user " . $sql_arr['user_id'] . "...";
 
diff --git a/bin/updatedb.sh b/bin/updatedb.sh
index 964bc18..e981807 100755
--- a/bin/updatedb.sh
+++ b/bin/updatedb.sh
@@ -55,9 +55,9 @@
 
 // Read DB schema version from database (if 'system' table exists)
 if (in_array($DB->table_name('system'), (array)$DB->list_tables())) {
-    $DB->query("SELECT " . $DB->quote_identifier('value')
-        ." FROM " . $DB->quote_identifier($DB->table_name('system'))
-        ." WHERE " . $DB->quote_identifier('name') ." = ?",
+    $DB->query("SELECT `value`"
+        ." FROM " . $DB->table_name('system', true)
+        ." WHERE `name` = ?",
         $opts['package'] . '-version');
 
     $row     = $DB->fetch_array();
@@ -159,17 +159,16 @@
         return;
     }
 
-    $system_table = $DB->quote_identifier($DB->table_name('system'));
+    $system_table = $DB->table_name('system', true);
 
     $DB->query("UPDATE " . $system_table
-        ." SET " . $DB->quote_identifier('value') . " = ?"
-        ." WHERE " . $DB->quote_identifier('name') . " = ?",
+        ." SET `value` = ?"
+        ." WHERE `name` = ?",
         $version, $package . '-version');
 
     if (!$DB->is_error() && !$DB->affected_rows()) {
         $DB->query("INSERT INTO " . $system_table
-            ." (" . $DB->quote_identifier('name') . ", " . $DB->quote_identifier('value') . ")"
-            ." VALUES (?, ?)",
+            ." (`name`, `value`) VALUES (?, ?)",
             $package . '-version', $version);
     }
 
diff --git a/installer/test.php b/installer/test.php
index 72c7a1f..988451e 100644
--- a/installer/test.php
+++ b/installer/test.php
@@ -154,7 +154,7 @@
 
 // test database
 if ($db_working) {
-    $db_read = $DB->query("SELECT count(*) FROM {$RCI->config['db_prefix']}users");
+    $db_read = $DB->query("SELECT count(*) FROM " . $DB->quote_identifier($RCI->config['db_prefix'] . 'users'));
     if ($DB->is_error()) {
         $RCI->fail('DB Schema', "Database not initialized");
         echo '<p><input type="submit" name="initdb" value="Initialize database" /></p>';
@@ -178,17 +178,19 @@
 if ($db_working) {
     // write test
     $insert_id = md5(uniqid());
-    $db_write = $DB->query("INSERT INTO {$RCI->config['db_prefix']}session (sess_id, created, ip, vars) VALUES (?, ".$DB->now().", '127.0.0.1', 'foo')", $insert_id);
+    $db_write = $DB->query("INSERT INTO " . $DB->quote_identifier($RCI->config['db_prefix'] . 'session')
+        . " (`sess_id`, `created`, `ip`, `vars`) VALUES (?, ".$DB->now().", '127.0.0.1', 'foo')", $insert_id);
 
     if ($db_write) {
       $RCI->pass('DB Write');
-      $DB->query("DELETE FROM {$RCI->config['db_prefix']}session WHERE sess_id=?", $insert_id);
+      $DB->query("DELETE FROM " . $DB->quote_identifier($RCI->config['db_prefix'] . 'session')
+        . " WHERE `sess_id` = ?", $insert_id);
     }
     else {
       $RCI->fail('DB Write', $RCI->get_error());
     }
     echo '<br />';
-    
+
     // check timezone settings
     $tz_db = 'SELECT ' . $DB->unixtimestamp($DB->now()) . ' AS tz_db';
     $tz_db = $DB->query($tz_db);
diff --git a/plugins/squirrelmail_usercopy/squirrelmail_usercopy.php b/plugins/squirrelmail_usercopy/squirrelmail_usercopy.php
index e882a2f..7f37867 100644
--- a/plugins/squirrelmail_usercopy/squirrelmail_usercopy.php
+++ b/plugins/squirrelmail_usercopy/squirrelmail_usercopy.php
@@ -164,14 +164,16 @@
 			if ($db_charset)
 				$db->query('SET NAMES '.$db_charset);
 
-			$sql_result = $db->query('SELECT * FROM '.$userprefs_table.' WHERE user=?', $uname); // ? is replaced with emailaddress
+			$sql_result = $db->query('SELECT * FROM ' . $db->quote_identifier($userprefs_table)
+			    .' WHERE `user` = ?', $uname); // ? is replaced with emailaddress
 
 			while ($sql_array = $db->fetch_assoc($sql_result) ) { // fetch one row from result
 				$this->prefs[$sql_array['prefkey']] = rcube_charset::convert(rtrim($sql_array['prefval']), $db_charset);
 			}
 
 			/* retrieve address table data */
-			$sql_result = $db->query('SELECT * FROM '.$address_table.' WHERE owner=?', $uname); // ? is replaced with emailaddress
+			$sql_result = $db->query('SELECT * FROM ' . $db->quote_identifier($address_table)
+			    .' WHERE `owner` = ?', $uname); // ? is replaced with emailaddress
 
 			// parse addres book
 			while ($sql_array = $db->fetch_assoc($sql_result) ) { // fetch one row from result
@@ -186,5 +188,4 @@
 			}
 		} // end if 'sql'-driver
 	}
-
 }
diff --git a/program/lib/Roundcube/rcube_cache.php b/program/lib/Roundcube/rcube_cache.php
index 0017dca..7210ce6 100644
--- a/program/lib/Roundcube/rcube_cache.php
+++ b/program/lib/Roundcube/rcube_cache.php
@@ -75,7 +75,7 @@
         else {
             $this->type  = 'db';
             $this->db    = $rcube->get_dbh();
-            $this->table = $this->db->table_name('cache');
+            $this->table = $this->db->table_name('cache', true);
         }
 
         // convert ttl string to seconds
@@ -197,10 +197,10 @@
     {
         if ($this->type == 'db' && $this->db && $this->ttl) {
             $this->db->query(
-                "DELETE FROM ".$this->table.
-                " WHERE user_id = ?".
-                " AND cache_key LIKE ?".
-                " AND expires < " . $this->db->now(),
+                "DELETE FROM {$this->table}".
+                " WHERE `user_id` = ?".
+                " AND `cache_key` LIKE ?".
+                " AND `expires` < " . $this->db->now(),
                 $this->userid,
                 $this->prefix.'.%');
         }
@@ -215,7 +215,7 @@
         $rcube = rcube::get_instance();
         $db    = $rcube->get_dbh();
 
-        $db->query("DELETE FROM " . $db->table_name('cache') . " WHERE expires < " . $db->now());
+        $db->query("DELETE FROM " . $db->table_name('cache', true) . " WHERE `expires` < " . $db->now());
     }
 
 
@@ -284,13 +284,12 @@
         }
         else {
             $sql_result = $this->db->limitquery(
-                "SELECT data, cache_key".
-                " FROM " . $this->table.
-                " WHERE user_id = ?".
-                " AND cache_key = ?".
+                "SELECT `data`, `cache_key`".
+                " FROM {$this->table}".
+                " WHERE `user_id` = ? AND `cache_key` = ?".
                 // for better performance we allow more records for one key
                 // get the newer one
-                " ORDER BY created DESC",
+                " ORDER BY `created` DESC",
                 0, 1, $this->userid, $this->prefix.'.'.$key);
 
             if ($sql_arr = $this->db->fetch_assoc($sql_result)) {
@@ -346,9 +345,8 @@
         // Remove NULL rows (here we don't need to check if the record exist)
         if ($data == 'N;') {
             $this->db->query(
-                "DELETE FROM " . $this->table.
-                " WHERE user_id = ?".
-                " AND cache_key = ?",
+                "DELETE FROM {$this->table}".
+                " WHERE `user_id` = ? AND `cache_key` = ?",
                 $this->userid, $key);
 
             return true;
@@ -357,12 +355,12 @@
         // update existing cache record
         if ($key_exists) {
             $result = $this->db->query(
-                "UPDATE " . $this->table.
-                " SET created = " . $this->db->now().
-                    ", expires = " . ($this->ttl ? $this->db->now($this->ttl) : 'NULL').
-                    ", data = ?".
-                " WHERE user_id = ?".
-                " AND cache_key = ?",
+                "UPDATE {$this->table}".
+                " SET `created` = " . $this->db->now().
+                    ", `expires` = " . ($this->ttl ? $this->db->now($this->ttl) : 'NULL').
+                    ", `data` = ?".
+                " WHERE `user_id` = ?".
+                " AND `cache_key` = ?",
                 $data, $this->userid, $key);
         }
         // add new cache record
@@ -370,8 +368,8 @@
             // for better performance we allow more records for one key
             // so, no need to check if record exist (see rcube_cache::read_record())
             $result = $this->db->query(
-                "INSERT INTO " . $this->table.
-                " (created, expires, user_id, cache_key, data)".
+                "INSERT INTO {$this->table}".
+                " (`created`, `expires`, `user_id`, `cache_key`, `data`)".
                 " VALUES (" . $this->db->now() . ", " . ($this->ttl ? $this->db->now($this->ttl) : 'NULL') . ", ?, ?, ?)",
                 $this->userid, $key, $data);
         }
@@ -421,20 +419,19 @@
 
         // Remove all keys (in specified cache)
         if ($key === null) {
-            $where = " AND cache_key LIKE " . $this->db->quote($this->prefix.'.%');
+            $where = " AND `cache_key` LIKE " . $this->db->quote($this->prefix.'.%');
         }
         // Remove keys by name prefix
         else if ($prefix_mode) {
-            $where = " AND cache_key LIKE " . $this->db->quote($this->prefix.'.'.$key.'%');
+            $where = " AND `cache_key` LIKE " . $this->db->quote($this->prefix.'.'.$key.'%');
         }
         // Remove one key by name
         else {
-            $where = " AND cache_key = " . $this->db->quote($this->prefix.'.'.$key);
+            $where = " AND `cache_key` = " . $this->db->quote($this->prefix.'.'.$key);
         }
 
         $this->db->query(
-            "DELETE FROM " . $this->table.
-            " WHERE user_id = ?" . $where,
+            "DELETE FROM {$this->table} WHERE `user_id` = ?" . $where,
             $this->userid);
     }
 
diff --git a/program/lib/Roundcube/rcube_cache_shared.php b/program/lib/Roundcube/rcube_cache_shared.php
index 8f25740..a2bf092 100644
--- a/program/lib/Roundcube/rcube_cache_shared.php
+++ b/program/lib/Roundcube/rcube_cache_shared.php
@@ -72,7 +72,7 @@
         else {
             $this->type  = 'db';
             $this->db    = $rcube->get_dbh();
-            $this->table = $this->db->table_name('cache_shared');
+            $this->table = $this->db->table_name('cache_shared', true);
         }
 
         // convert ttl string to seconds
@@ -193,9 +193,9 @@
     {
         if ($this->type == 'db' && $this->db && $this->ttl) {
             $this->db->query(
-                "DELETE FROM " . $this->table
-                . " WHERE cache_key LIKE ?"
-                . " AND expires < " . $this->db->now(),
+                "DELETE FROM {$this->table}"
+                . " WHERE `cache_key` LIKE ?"
+                . " AND `expires` < " . $this->db->now(),
                 $this->prefix . '.%');
         }
     }
@@ -209,7 +209,7 @@
         $rcube = rcube::get_instance();
         $db    = $rcube->get_dbh();
 
-        $db->query("DELETE FROM " . $db->table_name('cache_shared') . " WHERE expires < " . $db->now());
+        $db->query("DELETE FROM " . $db->table_name('cache_shared', true) . " WHERE `expires` < " . $db->now());
     }
 
 
@@ -278,12 +278,12 @@
         }
         else {
             $sql_result = $this->db->limitquery(
-                "SELECT data, cache_key".
-                " FROM " . $this->table .
-                " WHERE cache_key = ?".
+                "SELECT `data`, `cache_key`".
+                " FROM {$this->table}" .
+                " WHERE `cache_key` = ?".
                 // for better performance we allow more records for one key
                 // get the newer one
-                " ORDER BY created DESC",
+                " ORDER BY `created` DESC",
                 0, 1, $this->prefix . '.' . $key);
 
             if ($sql_arr = $this->db->fetch_assoc($sql_result)) {
@@ -331,18 +331,18 @@
 
         // Remove NULL rows (here we don't need to check if the record exist)
         if ($data == 'N;') {
-            $this->db->query("DELETE FROM " . $this->table . " WHERE cache_key = ?", $key);
+            $this->db->query("DELETE FROM {$this->table} WHERE `cache_key` = ?", $key);
             return true;
         }
 
         // update existing cache record
         if ($key_exists) {
             $result = $this->db->query(
-                "UPDATE " . $this->table .
-                " SET created = " . $this->db->now() .
-                    ", expires = " . ($this->ttl ? $this->db->now($this->ttl) : 'NULL') .
-                    ", data = ?".
-                " WHERE cache_key = ?",
+                "UPDATE {$this->table}" .
+                " SET `created` = " . $this->db->now() .
+                    ", `expires` = " . ($this->ttl ? $this->db->now($this->ttl) : 'NULL') .
+                    ", `data` = ?".
+                " WHERE `cache_key` = ?",
                 $data, $key);
         }
         // add new cache record
@@ -350,8 +350,8 @@
             // for better performance we allow more records for one key
             // so, no need to check if record exist (see rcube_cache::read_record())
             $result = $this->db->query(
-                "INSERT INTO ".$this->table.
-                " (created, expires, cache_key, data)".
+                "INSERT INTO {$this->table}".
+                " (`created`, `expires`, `cache_key`, `data`)".
                 " VALUES (".$this->db->now().", " . ($this->ttl ? $this->db->now($this->ttl) : 'NULL') . ", ?, ?)",
                 $key, $data);
         }
@@ -401,15 +401,15 @@
 
         // Remove all keys (in specified cache)
         if ($key === null) {
-            $where = " WHERE cache_key LIKE " . $this->db->quote($this->prefix.'.%');
+            $where = " WHERE `cache_key` LIKE " . $this->db->quote($this->prefix.'.%');
         }
         // Remove keys by name prefix
         else if ($prefix_mode) {
-            $where = " WHERE cache_key LIKE " . $this->db->quote($this->prefix.'.'.$key.'%');
+            $where = " WHERE `cache_key` LIKE " . $this->db->quote($this->prefix.'.'.$key.'%');
         }
         // Remove one key by name
         else {
-            $where = " WHERE cache_key = " . $this->db->quote($this->prefix.'.'.$key);
+            $where = " WHERE `cache_key` = " . $this->db->quote($this->prefix.'.'.$key);
         }
 
         $this->db->query("DELETE FROM " . $this->table . $where);
diff --git a/program/lib/Roundcube/rcube_contacts.php b/program/lib/Roundcube/rcube_contacts.php
index 5e1a40e..bd3a3f8 100644
--- a/program/lib/Roundcube/rcube_contacts.php
+++ b/program/lib/Roundcube/rcube_contacts.php
@@ -167,11 +167,9 @@
         }
 
         $sql_result = $this->db->query(
-            "SELECT * FROM ".$this->db->table_name($this->db_groups).
-            " WHERE del<>1".
-            " AND user_id=?".
-            $sql_filter.
-            " ORDER BY name",
+            "SELECT * FROM " . $this->db->table_name($this->db_groups, true)
+            . " WHERE `del` <> 1 AND `user_id` = ?" . $sql_filter
+            . " ORDER BY `name`",
             $this->user_id);
 
         while ($sql_result && ($sql_arr = $this->db->fetch_assoc($sql_result))) {
@@ -192,10 +190,8 @@
     function get_group($group_id)
     {
         $sql_result = $this->db->query(
-            "SELECT * FROM ".$this->db->table_name($this->db_groups).
-            " WHERE del<>1".
-            " AND contactgroup_id=?".
-            " AND user_id=?",
+            "SELECT * FROM " . $this->db->table_name($this->db_groups, true)
+            . " WHERE `del` <> 1 AND `contactgroup_id` = ? AND `user_id` = ?",
             $group_id, $this->user_id);
 
         if ($sql_result && ($sql_arr = $this->db->fetch_assoc($sql_result))) {
@@ -228,25 +224,25 @@
         $length = $subset != 0 ? abs($subset) : $this->page_size;
 
         if ($this->group_id)
-            $join = " LEFT JOIN ".$this->db->table_name($this->db_groupmembers)." AS m".
-                " ON (m.contact_id = c.".$this->primary_key.")";
+            $join = " LEFT JOIN " . $this->db->table_name($this->db_groupmembers, true) . " AS m".
+                " ON (m.`contact_id` = c.`".$this->primary_key."`)";
 
         $order_col = (in_array($this->sort_col, $this->table_cols) ? $this->sort_col : 'name');
-        $order_cols = array('c.'.$order_col);
+        $order_cols = array("c.`$order_col`");
         if ($order_col == 'firstname')
-            $order_cols[] = 'c.surname';
+            $order_cols[] = 'c.`surname`';
         else if ($order_col == 'surname')
-            $order_cols[] = 'c.firstname';
+            $order_cols[] = 'c.`firstname`';
         if ($order_col != 'name')
-            $order_cols[] = 'c.name';
-        $order_cols[] = 'c.email';
+            $order_cols[] = 'c.`name`';
+        $order_cols[] = 'c.`email`';
 
         $sql_result = $this->db->limitquery(
-            "SELECT * FROM ".$this->db->table_name($this->db_name)." AS c" .
+            "SELECT * FROM " . $this->db->table_name($this->db_name, true) . " AS c" .
             $join .
-            " WHERE c.del<>1" .
-                " AND c.user_id=?" .
-                ($this->group_id ? " AND m.contactgroup_id=?" : "").
+            " WHERE c.`del` <> 1" .
+                " AND c.`user_id` = ?" .
+                ($this->group_id ? " AND m.`contactgroup_id` = ?" : "").
                 ($this->filter ? " AND (".$this->filter.")" : "") .
             " ORDER BY ". $this->db->concat($order_cols) .
             " " . $this->sort_order,
@@ -442,7 +438,7 @@
 
             // build WHERE clause
             $ids = $this->db->array2list($ids, 'integer');
-            $where = 'c.' . $this->primary_key.' IN ('.$ids.')';
+            $where = 'c.`' . $this->primary_key.'` IN ('.$ids.')';
             // reset counter
             unset($this->cache['count']);
 
@@ -486,17 +482,17 @@
     private function _count()
     {
         if ($this->group_id)
-            $join = " LEFT JOIN ".$this->db->table_name($this->db_groupmembers)." AS m".
-                " ON (m.contact_id=c.".$this->primary_key.")";
+            $join = " LEFT JOIN " . $this->db->table_name($this->db_groupmembers, true) . " AS m".
+                " ON (m.`contact_id` = c.`".$this->primary_key."`)";
 
         // count contacts for this user
         $sql_result = $this->db->query(
-            "SELECT COUNT(c.contact_id) AS rows".
-            " FROM ".$this->db->table_name($this->db_name)." AS c".
+            "SELECT COUNT(c.`contact_id`) AS rows".
+            " FROM " . $this->db->table_name($this->db_name, true) . " AS c".
                 $join.
-            " WHERE c.del<>1".
-            " AND c.user_id=?".
-            ($this->group_id ? " AND m.contactgroup_id=?" : "").
+            " WHERE c.`del` <> 1".
+            " AND c.`user_id` = ?".
+            ($this->group_id ? " AND m.`contactgroup_id` = ?" : "").
             ($this->filter ? " AND (".$this->filter.")" : ""),
             $this->user_id,
             $this->group_id
@@ -534,10 +530,10 @@
             return $assoc ? $first : $this->result;
 
         $this->db->query(
-            "SELECT * FROM ".$this->db->table_name($this->db_name).
-            " WHERE contact_id=?".
-                " AND user_id=?".
-                " AND del<>1",
+            "SELECT * FROM " . $this->db->table_name($this->db_name, true).
+            " WHERE `contact_id` = ?".
+                " AND `user_id` = ?".
+                " AND `del` <> 1",
             $id,
             $this->user_id
         );
@@ -566,9 +562,11 @@
           return $results;
 
       $sql_result = $this->db->query(
-        "SELECT cgm.contactgroup_id, cg.name FROM " . $this->db->table_name($this->db_groupmembers) . " AS cgm" .
-        " LEFT JOIN " . $this->db->table_name($this->db_groups) . " AS cg ON (cgm.contactgroup_id = cg.contactgroup_id AND cg.del<>1)" .
-        " WHERE cgm.contact_id=?",
+        "SELECT cgm.`contactgroup_id`, cg.`name` "
+        . " FROM " . $this->db->table_name($this->db_groupmembers, true) . " AS cgm"
+        . " LEFT JOIN " . $this->db->table_name($this->db_groups, true) . " AS cg"
+            . " ON (cgm.`contactgroup_id` = cg.`contactgroup_id` AND cg.`del` <> 1)"
+        . " WHERE cgm.`contact_id` = ?",
         $id
       );
       while ($sql_result && ($sql_arr = $this->db->fetch_assoc($sql_result))) {
@@ -636,8 +634,8 @@
 
         if (!$existing->count && !empty($a_insert_cols)) {
             $this->db->query(
-                "INSERT INTO ".$this->db->table_name($this->db_name).
-                " (user_id, changed, del, ".join(', ', $a_insert_cols).")".
+                "INSERT INTO " . $this->db->table_name($this->db_name, true).
+                " (`user_id`, `changed`, `del`, ".join(', ', $a_insert_cols).")".
                 " VALUES (".intval($this->user_id).", ".$this->db->now().", 0, ".join(', ', $a_insert_values).")"
             );
 
@@ -671,11 +669,11 @@
 
         if (!empty($write_sql)) {
             $this->db->query(
-                "UPDATE ".$this->db->table_name($this->db_name).
-                " SET changed=".$this->db->now().", ".join(', ', $write_sql).
-                " WHERE contact_id=?".
-                    " AND user_id=?".
-                    " AND del<>1",
+                "UPDATE " . $this->db->table_name($this->db_name, true).
+                " SET `changed` = ".$this->db->now().", ".join(', ', $write_sql).
+                " WHERE `contact_id` = ?".
+                    " AND `user_id` = ?".
+                    " AND `del` <> 1",
                 $id,
                 $this->user_id
             );
@@ -771,10 +769,10 @@
 
         // flag record as deleted (always)
         $this->db->query(
-            "UPDATE ".$this->db->table_name($this->db_name).
-            " SET del=1, changed=".$this->db->now().
-            " WHERE user_id=?".
-                " AND contact_id IN ($ids)",
+            "UPDATE " . $this->db->table_name($this->db_name, true).
+            " SET `del` = 1, `changed` = ".$this->db->now().
+            " WHERE `user_id` = ?".
+                " AND `contact_id` IN ($ids)",
             $this->user_id
         );
 
@@ -798,10 +796,10 @@
 
         // clear deleted flag
         $this->db->query(
-            "UPDATE ".$this->db->table_name($this->db_name).
-            " SET del=0, changed=".$this->db->now().
-            " WHERE user_id=?".
-                " AND contact_id IN ($ids)",
+            "UPDATE " . $this->db->table_name($this->db_name, true).
+            " SET `del` = 0, `changed` = ".$this->db->now().
+            " WHERE `user_id` = ?".
+                " AND `contact_id` IN ($ids)",
             $this->user_id
         );
 
@@ -822,16 +820,18 @@
     {
         $this->cache = null;
 
-        $this->db->query("UPDATE " . $this->db->table_name($this->db_name)
-            . " SET del = 1, changed = " . $this->db->now()
-            . " WHERE user_id = ?", $this->user_id);
+        $now = $this->db->now();
+
+        $this->db->query("UPDATE " . $this->db->table_name($this->db_name, true)
+            . " SET `del` = 1, `changed` = $now"
+            . " WHERE `user_id` = ?", $this->user_id);
 
         $count = $this->db->affected_rows();
 
         if ($with_groups) {
-            $this->db->query("UPDATE " . $this->db->table_name($this->db_groups)
-                . " SET del = 1, changed = " . $this->db->now()
-                . " WHERE user_id = ?", $this->user_id);
+            $this->db->query("UPDATE " . $this->db->table_name($this->db_groups, true)
+                . " SET `del` = 1, `changed` = $now"
+                . " WHERE `user_id` = ?", $this->user_id);
 
             $count += $this->db->affected_rows();
         }
@@ -854,13 +854,14 @@
         $name = $this->unique_groupname($name);
 
         $this->db->query(
-            "INSERT INTO ".$this->db->table_name($this->db_groups).
-            " (user_id, changed, name)".
+            "INSERT INTO " . $this->db->table_name($this->db_groups, true).
+            " (`user_id`, `changed`, `name`)".
             " VALUES (".intval($this->user_id).", ".$this->db->now().", ".$this->db->quote($name).")"
         );
 
-        if ($insert_id = $this->db->insert_id($this->db_groups))
+        if ($insert_id = $this->db->insert_id($this->db_groups)) {
             $result = array('id' => $insert_id, 'name' => $name);
+        }
 
         return $result;
     }
@@ -876,10 +877,10 @@
     {
         // flag group record as deleted
         $this->db->query(
-            "UPDATE " . $this->db->table_name($this->db_groups)
-            . " SET del = 1, changed = " . $this->db->now()
-            . " WHERE contactgroup_id = ?"
-            . " AND user_id = ?",
+            "UPDATE " . $this->db->table_name($this->db_groups, true)
+            . " SET `del` = 1, `changed` = " . $this->db->now()
+            . " WHERE `contactgroup_id` = ?"
+                . " AND `user_id` = ?",
             $gid, $this->user_id
         );
 
@@ -901,10 +902,10 @@
         $name = $this->unique_groupname($newname);
 
         $sql_result = $this->db->query(
-            "UPDATE ".$this->db->table_name($this->db_groups).
-            " SET name=?, changed=".$this->db->now().
-            " WHERE contactgroup_id=?".
-            " AND user_id=?",
+            "UPDATE " . $this->db->table_name($this->db_groups, true).
+            " SET `name` = ?, `changed` = ".$this->db->now().
+            " WHERE `contactgroup_id` = ?".
+                " AND `user_id` = ?",
             $name, $gid, $this->user_id
         );
 
@@ -930,9 +931,9 @@
 
         // get existing assignments ...
         $sql_result = $this->db->query(
-            "SELECT contact_id FROM ".$this->db->table_name($this->db_groupmembers).
-            " WHERE contactgroup_id=?".
-                " AND contact_id IN (".$this->db->array2list($ids, 'integer').")",
+            "SELECT `contact_id` FROM " . $this->db->table_name($this->db_groupmembers, true).
+            " WHERE `contactgroup_id` = ?".
+                " AND `contact_id` IN (".$this->db->array2list($ids, 'integer').")",
             $group_id
         );
         while ($sql_result && ($sql_arr = $this->db->fetch_assoc($sql_result))) {
@@ -943,8 +944,8 @@
 
         foreach ($ids as $contact_id) {
             $this->db->query(
-                "INSERT INTO ".$this->db->table_name($this->db_groupmembers).
-                " (contactgroup_id, contact_id, created)".
+                "INSERT INTO " . $this->db->table_name($this->db_groupmembers, true).
+                " (`contactgroup_id`, `contact_id`, `created`)".
                 " VALUES (?, ?, ".$this->db->now().")",
                 $group_id,
                 $contact_id
@@ -976,9 +977,9 @@
         $ids = $this->db->array2list($ids, 'integer');
 
         $sql_result = $this->db->query(
-            "DELETE FROM ".$this->db->table_name($this->db_groupmembers).
-            " WHERE contactgroup_id=?".
-                " AND contact_id IN ($ids)",
+            "DELETE FROM " . $this->db->table_name($this->db_groupmembers, true).
+            " WHERE `contactgroup_id` = ?".
+                " AND `contact_id` IN ($ids)",
             $group_id
         );
 
@@ -999,10 +1000,10 @@
 
         do {
             $sql_result = $this->db->query(
-                "SELECT 1 FROM ".$this->db->table_name($this->db_groups).
-                " WHERE del<>1".
-                    " AND user_id=?".
-                    " AND name=?",
+                "SELECT 1 FROM " . $this->db->table_name($this->db_groups, true).
+                " WHERE `del` <> 1".
+                    " AND `user_id` = ?".
+                    " AND `name` = ?",
                 $this->user_id,
                 $checkname);
 
@@ -1014,5 +1015,4 @@
 
         return $checkname;
     }
-
 }
diff --git a/program/lib/Roundcube/rcube_db.php b/program/lib/Roundcube/rcube_db.php
index 100afd5..b12c99d 100644
--- a/program/lib/Roundcube/rcube_db.php
+++ b/program/lib/Roundcube/rcube_db.php
@@ -50,6 +50,7 @@
     );
 
     const DEBUG_LINE_LENGTH = 4096;
+    const DEFAULT_QUOTE     = '`';
 
     /**
      * Factory, returns driver-specific instance of the class
@@ -238,8 +239,12 @@
         // Read or write ?
         $mode = preg_match('/^(select|show|set)/i', $query) ? 'r' : 'w';
 
+        $start = '[' . $this->options['identifier_start'] . self::DEFAULT_QUOTE . ']';
+        $end   = '[' . $this->options['identifier_end']   . self::DEFAULT_QUOTE . ']';
+        $regex = '/(?:^|\s)(from|update|into|join)\s+'.$start.'?([a-z0-9._]+)'.$end.'?\s+/i';
+
         // find tables involved in this query
-        if (preg_match_all('/(?:^|\s)(from|update|into|join)\s+'.$this->options['identifier_start'].'?([a-z0-9._]+)'.$this->options['identifier_end'].'?\s+/i', $query, $matches, PREG_SET_ORDER)) {
+        if (preg_match_all($regex, $query, $matches, PREG_SET_ORDER)) {
             foreach ($matches as $m) {
                 $table = $m[2];
 
@@ -408,6 +413,9 @@
             $query = $this->set_limit($query, $numrows, $offset);
         }
 
+        // replace self::DEFAULT_QUOTE with driver-specific quoting
+        $query = $this->query_parse($query);
+
         // Because in Roundcube we mostly use queries that are
         // executed only once, we will not use prepared queries
         $pos = 0;
@@ -431,6 +439,7 @@
         $query = str_replace('??', '?', $query);
         $query = rtrim($query, " \t\n\r\0\x0B;");
 
+        // log query
         $this->debug($query);
 
         // destroy reference to previous result, required for SQLite driver (#1488874)
@@ -447,6 +456,51 @@
         $this->last_result = $result;
 
         return $result;
+    }
+
+    /**
+     * Parse SQL query and replace identifier quoting
+     *
+     * @param string $query SQL query
+     *
+     * @return string SQL query
+     */
+    protected function query_parse($query)
+    {
+        $start = $this->options['identifier_start'];
+        $end   = $this->options['identifier_end'];
+        $quote = self::DEFAULT_QUOTE;
+
+        if ($start == $quote) {
+            return $query;
+        }
+
+        $pos = 0;
+        $in  = false;
+
+        while ($pos = strpos($query, $quote, $pos)) {
+            if ($query[$pos+1] == $quote) {  // skip escaped quote
+                $pos += 2;
+            }
+            else {
+                if ($in) {
+                    $q  = $end;
+                    $in = false;
+                }
+                else {
+                    $q  = $start;
+                    $in = true;
+                }
+
+                $query = substr_replace($query, $q, $pos, 1);
+                $pos++;
+            }
+        }
+
+        // replace escaped quote back to normal, see self::quote()
+        $query = str_replace($quote.$quote, $quote, $query);
+
+        return $query;
     }
 
     /**
@@ -677,8 +731,13 @@
                 'bool'    => PDO::PARAM_BOOL,
                 'integer' => PDO::PARAM_INT,
             );
+
             $type = isset($map[$type]) ? $map[$type] : PDO::PARAM_STR;
-            return strtr($this->dbh->quote($input, $type), array('?' => '??'));  // escape ?
+
+            return strtr($this->dbh->quote($input, $type),
+                // escape ? and `
+                array('?' => '??', self::DEFAULT_QUOTE => self::DEFAULT_QUOTE.self::DEFAULT_QUOTE)
+            );
         }
 
         return 'NULL';
@@ -917,15 +976,20 @@
     /**
      * Return correct name for a specific database table
      *
-     * @param string $table Table name
+     * @param string $table  Table name
+     * @param bool   $quoted Quote table identifier
      *
      * @return string Translated table name
      */
-    public function table_name($table)
+    public function table_name($table, $quoted = false)
     {
         // add prefix to the table name if configured
         if (($prefix = $this->options['table_prefix']) && strpos($table, $prefix) !== 0) {
-            return $prefix . $table;
+            $table = $prefix . $table;
+        }
+
+        if ($quoted) {
+            $table = $this->quote_identifier($table);
         }
 
         return $table;
diff --git a/program/lib/Roundcube/rcube_imap_cache.php b/program/lib/Roundcube/rcube_imap_cache.php
index e49e778..5191321 100644
--- a/program/lib/Roundcube/rcube_imap_cache.php
+++ b/program/lib/Roundcube/rcube_imap_cache.php
@@ -125,6 +125,11 @@
 
         // 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);
     }
 
 
@@ -333,11 +338,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);
@@ -400,11 +405,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)) {
@@ -480,11 +485,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)) {
@@ -496,8 +501,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);
 
@@ -505,12 +510,12 @@
         // 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);
         }
 
@@ -558,13 +563,13 @@
         }
 
         $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 (`flags` & $idx) ".($enabled ? "= 0" : "= $idx"),
             $this->userid, $mailbox);
     }
 
@@ -583,8 +588,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 {
@@ -597,10 +602,10 @@
             }
 
             $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);
         }
     }
@@ -619,18 +624,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
             );
         }
@@ -654,9 +659,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
         );
 
@@ -692,15 +697,16 @@
     {
         $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");
     }
 
 
@@ -711,10 +717,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)) {
@@ -748,10 +754,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)) {
@@ -789,14 +795,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)) {
@@ -807,19 +815,19 @@
         $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);
         }
 
@@ -838,16 +846,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)) {
@@ -858,8 +866,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);
 
@@ -867,10 +875,10 @@
         // 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);
         }
 
@@ -1086,10 +1094,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)) {
@@ -1125,12 +1133,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);
                 }
             }
diff --git a/program/lib/Roundcube/rcube_session.php b/program/lib/Roundcube/rcube_session.php
index 26f7843..8306a06 100644
--- a/program/lib/Roundcube/rcube_session.php
+++ b/program/lib/Roundcube/rcube_session.php
@@ -103,6 +103,8 @@
                 array($this, 'db_write'),
                 array($this, 'db_destroy'),
                 array($this, 'gc'));
+
+            $this->table_name = $this->db->table_name('session', true);
         }
     }
 
@@ -175,9 +177,8 @@
     public function db_read($key)
     {
         $sql_result = $this->db->query(
-            "SELECT vars, ip, changed, " . $this->db->now() . " AS ts"
-            . " FROM " . $this->db->table_name('session')
-            . " WHERE sess_id = ?", $key);
+            "SELECT `vars`, `ip`, `changed`, " . $this->db->now() . " AS ts"
+            . " FROM {$this->table_name} WHERE `sess_id` = ?", $key);
 
         if ($sql_result && ($sql_arr = $this->db->fetch_assoc($sql_result))) {
             $this->time_diff = time() - strtotime($sql_arr['ts']);
@@ -204,9 +205,8 @@
      */
     public function db_write($key, $vars)
     {
-        $now   = $this->db->now();
-        $table = $this->db->table_name('session');
-        $ts    = microtime(true);
+        $now = $this->db->now();
+        $ts  = microtime(true);
 
         if ($this->nowrite)
             return true;
@@ -227,17 +227,18 @@
             $newvars = $this->_fixvars($vars, $oldvars);
 
             if ($newvars !== $oldvars) {
-                $this->db->query("UPDATE $table "
-                    . "SET changed = $now, vars = ? WHERE sess_id = ?",
+                $this->db->query("UPDATE {$this->table_name} "
+                    . "SET `changed` = $now, `vars` = ? WHERE `sess_id` = ?",
                     base64_encode($newvars), $key);
             }
             else if ($ts - $this->changed + $this->time_diff > $this->lifetime / 2) {
-                $this->db->query("UPDATE $table SET changed = $now"
-                    . " WHERE sess_id = ?", $key);
+                $this->db->query("UPDATE {$this->table_name} SET `changed` = $now"
+                    . " WHERE `sess_id` = ?", $key);
             }
         }
         else {
-            $this->db->query("INSERT INTO $table (sess_id, vars, ip, created, changed)"
+            $this->db->query("INSERT INTO {$this->table_name}"
+                . " (`sess_id`, `vars`, `ip`, `created`, `changed`)"
                 . " VALUES (?, ?, ?, $now, $now)",
                 $key, base64_encode($vars), (string)$this->ip);
         }
@@ -290,8 +291,7 @@
     public function db_destroy($key)
     {
         if ($key) {
-            $this->db->query(sprintf("DELETE FROM %s WHERE sess_id = ?",
-                $this->db->table_name('session')), $key);
+            $this->db->query("DELETE FROM {$this->table_name} WHERE `sess_id` = ?", $key);
         }
 
         return true;
@@ -407,8 +407,8 @@
         if ($this->gc_enabled) {
             // just delete all expired sessions
             if ($this->storage == 'db') {
-                $this->db->query("DELETE FROM " . $this->db->table_name('session')
-                    . " WHERE changed < " . $this->db->now(-$this->gc_enabled));
+                $this->db->query("DELETE FROM {$this->table_name}"
+                    . " WHERE `changed` < " . $this->db->now(-$this->gc_enabled));
             }
 
             foreach ($this->gc_handlers as $fct) {
diff --git a/program/lib/Roundcube/rcube_spellchecker.php b/program/lib/Roundcube/rcube_spellchecker.php
index 43bab08..0627807 100644
--- a/program/lib/Roundcube/rcube_spellchecker.php
+++ b/program/lib/Roundcube/rcube_spellchecker.php
@@ -360,25 +360,25 @@
         if ($this->have_dict) {
             if (!empty($this->dict)) {
                 $this->rc->db->query(
-                    "UPDATE ".$this->rc->db->table_name('dictionary')
-                    ." SET data = ?"
-                    ." WHERE user_id " . ($plugin['userid'] ? "= ".$this->rc->db->quote($plugin['userid']) : "IS NULL")
-                        ." AND " . $this->rc->db->quote_identifier('language') . " = ?",
+                    "UPDATE " . $this->rc->db->table_name('dictionary', true)
+                    ." SET `data` = ?"
+                    ." WHERE `user_id` " . ($plugin['userid'] ? "= ".$this->rc->db->quote($plugin['userid']) : "IS NULL")
+                        ." AND `language` = ?",
                     implode(' ', $plugin['dictionary']), $plugin['language']);
             }
             // don't store empty dict
             else {
                 $this->rc->db->query(
-                    "DELETE FROM " . $this->rc->db->table_name('dictionary')
-                    ." WHERE user_id " . ($plugin['userid'] ? "= ".$this->rc->db->quote($plugin['userid']) : "IS NULL")
-                        ." AND " . $this->rc->db->quote_identifier('language') . " = ?",
+                    "DELETE FROM " . $this->rc->db->table_name('dictionary', true)
+                    ." WHERE `user_id` " . ($plugin['userid'] ? "= ".$this->rc->db->quote($plugin['userid']) : "IS NULL")
+                        ." AND `language` = ?",
                     $plugin['language']);
             }
         }
         else if (!empty($this->dict)) {
             $this->rc->db->query(
-                "INSERT INTO " .$this->rc->db->table_name('dictionary')
-                ." (user_id, " . $this->rc->db->quote_identifier('language') . ", data) VALUES (?, ?, ?)",
+                "INSERT INTO " . $this->rc->db->table_name('dictionary', true)
+                ." (`user_id`, `language`, `data`) VALUES (?, ?, ?)",
                 $plugin['userid'], $plugin['language'], implode(' ', $plugin['dictionary']));
         }
     }
@@ -403,9 +403,9 @@
         if (empty($plugin['abort'])) {
             $dict = array();
             $sql_result = $this->rc->db->query(
-                "SELECT data FROM ".$this->rc->db->table_name('dictionary')
-                ." WHERE user_id ". ($plugin['userid'] ? "= ".$this->rc->db->quote($plugin['userid']) : "IS NULL")
-                    ." AND " . $this->rc->db->quote_identifier('language') . " = ?",
+                "SELECT `data` FROM " . $this->rc->db->table_name('dictionary', true)
+                ." WHERE `user_id` ". ($plugin['userid'] ? "= ".$this->rc->db->quote($plugin['userid']) : "IS NULL")
+                    ." AND `language` = ?",
                 $plugin['language']);
 
             if ($sql_arr = $this->rc->db->fetch_assoc($sql_result)) {
@@ -427,5 +427,4 @@
 
         return $this->dict;
     }
-
 }
diff --git a/program/lib/Roundcube/rcube_user.php b/program/lib/Roundcube/rcube_user.php
index 739b6f2..b63cabe 100644
--- a/program/lib/Roundcube/rcube_user.php
+++ b/program/lib/Roundcube/rcube_user.php
@@ -67,7 +67,8 @@
 
         if ($id && !$sql_arr) {
             $sql_result = $this->db->query(
-                "SELECT * FROM ".$this->db->table_name('users')." WHERE user_id = ?", $id);
+                "SELECT * FROM " . $this->db->table_name('users', true)
+                . " WHERE `user_id` = ?", $id);
             $sql_arr = $this->db->fetch_assoc($sql_result);
         }
 
@@ -189,10 +190,9 @@
         $save_prefs = serialize($save_prefs);
 
         $this->db->query(
-            "UPDATE ".$this->db->table_name('users').
-            " SET preferences = ?".
-                ", language = ?".
-            " WHERE user_id = ?",
+            "UPDATE ".$this->db->table_name('users', true).
+            " SET `preferences` = ?, `language` = ?".
+            " WHERE `user_id` = ?",
             $save_prefs,
             $_SESSION['language'],
             $this->ID);
@@ -243,7 +243,7 @@
         $id = (int)$id;
         // cache identities for better performance
         if (!array_key_exists($id, $this->identities)) {
-            $result = $this->list_identities($id ? 'AND identity_id = ' . $id : '');
+            $result = $this->list_identities($id ? "AND `identity_id` = $id" : '');
             $this->identities[$id] = $result[0];
         }
 
@@ -264,13 +264,10 @@
         $result = array();
 
         $sql_result = $this->db->query(
-            "SELECT * FROM ".$this->db->table_name('identities').
-            " WHERE del <> 1 AND user_id = ?".
+            "SELECT * FROM ".$this->db->table_name('identities', true).
+            " WHERE `del` <> 1 AND `user_id` = ?".
             ($sql_add ? " ".$sql_add : "").
-            " ORDER BY ". $this->db->quote_identifier('standard') . " DESC, "
-                . $this->db->quote_identifier('name') . " ASC, "
-                . $this->db->quote_identifier('email') . " ASC, "
-                . $this->db->quote_identifier('identity_id') . " ASC",
+            " ORDER BY `standard` DESC, `name` ASC, `email` ASC, `identity_id` ASC",
             $this->ID);
 
         while ($sql_arr = $this->db->fetch_assoc($sql_result)) {
@@ -311,11 +308,11 @@
         $query_params[] = $iid;
         $query_params[] = $this->ID;
 
-        $sql = "UPDATE ".$this->db->table_name('identities').
-            " SET changed = ".$this->db->now().", ".join(', ', $query_cols).
-            " WHERE identity_id = ?".
-                " AND user_id = ?".
-                " AND del <> 1";
+        $sql = "UPDATE ".$this->db->table_name('identities', true).
+            " SET `changed` = ".$this->db->now().", ".join(', ', $query_cols).
+            " WHERE `identity_id` = ?".
+                " AND `user_id` = ?".
+                " AND `del` <> 1";
 
         call_user_func_array(array($this->db, 'query'),
             array_merge(array($sql), $query_params));
@@ -347,8 +344,8 @@
         $insert_cols[]   = 'user_id';
         $insert_values[] = $this->ID;
 
-        $sql = "INSERT INTO ".$this->db->table_name('identities').
-            " (changed, ".join(', ', $insert_cols).")".
+        $sql = "INSERT INTO ".$this->db->table_name('identities', true).
+            " (`changed`, ".join(', ', $insert_cols).")".
             " VALUES (".$this->db->now().", ".join(', ', array_pad(array(), sizeof($insert_values), '?')).")";
 
         call_user_func_array(array($this->db, 'query'),
@@ -372,8 +369,8 @@
             return false;
 
         $sql_result = $this->db->query(
-            "SELECT count(*) AS ident_count FROM ".$this->db->table_name('identities').
-            " WHERE user_id = ? AND del <> 1",
+            "SELECT count(*) AS ident_count FROM ".$this->db->table_name('identities', true).
+            " WHERE `user_id` = ? AND `del` <> 1",
             $this->ID);
 
         $sql_arr = $this->db->fetch_assoc($sql_result);
@@ -383,10 +380,10 @@
             return -1;
 
         $this->db->query(
-            "UPDATE ".$this->db->table_name('identities').
-            " SET del = 1, changed = ".$this->db->now().
-            " WHERE user_id = ?".
-                " AND identity_id = ?",
+            "UPDATE ".$this->db->table_name('identities', true).
+            " SET `del` = 1, `changed` = ".$this->db->now().
+            " WHERE `user_id` = ?".
+                " AND `identity_id` = ?",
             $this->ID,
             $iid);
 
@@ -405,11 +402,9 @@
     {
         if ($this->ID && $iid) {
             $this->db->query(
-                "UPDATE ".$this->db->table_name('identities').
-                " SET ".$this->db->quote_identifier('standard')." = '0'".
-                " WHERE user_id = ?".
-                    " AND identity_id <> ?".
-                    " AND del <> 1",
+                "UPDATE ".$this->db->table_name('identities', true).
+                " SET `standard` = '0'".
+                " WHERE `user_id` = ? AND `identity_id` <> ?",
                 $this->ID,
                 $iid);
 
@@ -425,9 +420,9 @@
     {
         if ($this->ID) {
             $this->db->query(
-                "UPDATE ".$this->db->table_name('users').
-                " SET last_login = ".$this->db->now().
-                " WHERE user_id = ?",
+                "UPDATE ".$this->db->table_name('users', true).
+                " SET `last_login` = ".$this->db->now().
+                " WHERE `user_id` = ?",
                 $this->ID);
         }
     }
@@ -456,17 +451,17 @@
         $config = rcube::get_instance()->config;
 
         // query for matching user name
-        $sql_result = $dbh->query("SELECT * FROM " . $dbh->table_name('users')
-            ." WHERE mail_host = ? AND username = ?", $host, $user);
+        $sql_result = $dbh->query("SELECT * FROM " . $dbh->table_name('users', true)
+            ." WHERE `mail_host` = ? AND `username` = ?", $host, $user);
 
         $sql_arr = $dbh->fetch_assoc($sql_result);
 
         // username not found, try aliases from identities
         if (empty($sql_arr) && $config->get('user_aliases') && strpos($user, '@')) {
             $sql_result = $dbh->limitquery("SELECT u.*"
-                ." FROM " . $dbh->table_name('users') . " u"
-                ." JOIN " . $dbh->table_name('identities') . " i ON (i.user_id = u.user_id)"
-                ." WHERE email = ? AND del <> 1", 0, 1, $user);
+                ." FROM " . $dbh->table_name('users', true) . " u"
+                ." JOIN " . $dbh->table_name('identities', true) . " i ON (i.`user_id` = u.`user_id`)"
+                ." WHERE `email` = ? AND `del` <> 1", 0, 1, $user);
 
             $sql_arr = $dbh->fetch_assoc($sql_result);
         }
@@ -513,8 +508,8 @@
         }
 
         $dbh->query(
-            "INSERT INTO ".$dbh->table_name('users').
-            " (created, last_login, username, mail_host, language)".
+            "INSERT INTO ".$dbh->table_name('users', true).
+            " (`created`, `last_login`, `username`, `mail_host`, `language`)".
             " VALUES (".$dbh->now().", ".$dbh->now().", ?, ?, ?)",
             $data['user'],
             $data['host'],
@@ -646,11 +641,10 @@
         $result = array();
 
         $sql_result = $this->db->query(
-            "SELECT search_id AS id, ".$this->db->quote_identifier('name')
-            ." FROM ".$this->db->table_name('searches')
-            ." WHERE user_id = ?"
-                ." AND ".$this->db->quote_identifier('type')." = ?"
-            ." ORDER BY ".$this->db->quote_identifier('name'),
+            "SELECT `search_id` AS id, `name`"
+            ." FROM ".$this->db->table_name('searches', true)
+            ." WHERE `user_id` = ? AND `type` = ?"
+            ." ORDER BY `name`",
             (int) $this->ID, (int) $type);
 
         while ($sql_arr = $this->db->fetch_assoc($sql_result)) {
@@ -678,12 +672,10 @@
         }
 
         $sql_result = $this->db->query(
-            "SELECT ".$this->db->quote_identifier('name')
-                .", ".$this->db->quote_identifier('data')
-                .", ".$this->db->quote_identifier('type')
-            ." FROM ".$this->db->table_name('searches')
-            ." WHERE user_id = ?"
-                ." AND search_id = ?",
+            "SELECT `name`, `data`, `type`"
+            . " FROM ".$this->db->table_name('searches', true)
+            . " WHERE `user_id` = ?"
+                ." AND `search_id` = ?",
             (int) $this->ID, (int) $id);
 
         while ($sql_arr = $this->db->fetch_assoc($sql_result)) {
@@ -712,9 +704,9 @@
             return false;
 
         $this->db->query(
-            "DELETE FROM ".$this->db->table_name('searches')
-            ." WHERE user_id = ?"
-                ." AND search_id = ?",
+            "DELETE FROM ".$this->db->table_name('searches', true)
+            ." WHERE `user_id` = ?"
+                ." AND `search_id` = ?",
             (int) $this->ID, $sid);
 
         return $this->db->affected_rows();
@@ -742,7 +734,7 @@
         $insert_cols[]   = $this->db->quote_identifier('data');
         $insert_values[] = serialize($data['data']);
 
-        $sql = "INSERT INTO ".$this->db->table_name('searches')
+        $sql = "INSERT INTO ".$this->db->table_name('searches', true)
             ." (".join(', ', $insert_cols).")"
             ." VALUES (".join(', ', array_pad(array(), sizeof($insert_values), '?')).")";
 
@@ -751,5 +743,4 @@
 
         return $this->db->insert_id('searches');
     }
-
 }
diff --git a/program/steps/utils/killcache.inc b/program/steps/utils/killcache.inc
index 1cb99b8..1adaebd 100644
--- a/program/steps/utils/killcache.inc
+++ b/program/steps/utils/killcache.inc
@@ -26,22 +26,27 @@
 }
 
 // @TODO: transaction here (if supported by DB) would be a good thing
-$res = $RCMAIL->db->query("DELETE FROM cache");
+$res = $RCMAIL->db->query("DELETE FROM " . $RCMAIL->db->table_name('cache', true));
 if ($err = $RCMAIL->db->is_error($res)) {
     exit($err);
 }
 
-$res = $RCMAIL->db->query("DELETE FROM cache_messages");
+$res = $RCMAIL->db->query("DELETE FROM " . $RCMAIL->db->table_name('cache_shared', true));
 if ($err = $RCMAIL->db->is_error($res)) {
     exit($err);
 }
 
-$res = $RCMAIL->db->query("DELETE FROM cache_index");
+$res = $RCMAIL->db->query("DELETE FROM " . $RCMAIL->db->table_name('cache_messages', true));
 if ($err = $RCMAIL->db->is_error($res)) {
     exit($err);
 }
 
-$res = $RCMAIL->db->query("DELETE FROM cache_thread");
+$res = $RCMAIL->db->query("DELETE FROM " . $RCMAIL->db->table_name('cache_index', true));
+if ($err = $RCMAIL->db->is_error($res)) {
+    exit($err);
+}
+
+$res = $RCMAIL->db->query("DELETE FROM " . $RCMAIL->db->table_name('cache_thread', true));
 if ($err = $RCMAIL->db->is_error($res)) {
     exit($err);
 }
diff --git a/tests/Framework/ImapCache.php b/tests/Framework/ImapCache.php
index 83612c5..6c7f988 100644
--- a/tests/Framework/ImapCache.php
+++ b/tests/Framework/ImapCache.php
@@ -13,7 +13,7 @@
      */
     function test_class()
     {
-        $object = new rcube_imap_cache(null, null, null, null);
+        $object = new rcube_imap_cache(new rcube_db('test'), null, null, null);
 
         $this->assertInstanceOf('rcube_imap_cache', $object, "Class constructor");
     }

--
Gitblit v1.9.1