Add ability to explicitly set prefs DB connection charset, though usually if database...
authorpdontthink <pdontthink@7612ce4b-ef26-0410-bec9-ea0150e637f0>
Fri, 27 May 2022 21:31:26 +0000 (21:31 +0000)
committerpdontthink <pdontthink@7612ce4b-ef26-0410-bec9-ea0150e637f0>
Fri, 27 May 2022 21:31:26 +0000 (21:31 +0000)
git-svn-id: https://svn.code.sf.net/p/squirrelmail/code/trunk/squirrelmail@14968 7612ce4b-ef26-0410-bec9-ea0150e637f0

config/config_local.example.php
functions/db_prefs.php

index d6918a2fdfcc7a675ce87a000f6ba3560fc1b720..d87bfa0e528ee93883e4899bc068fa50b0cd7f58 100644 (file)
  * being used (backtick for MySQL (and thus MariaDB),
  * double quotes for all others).
  *
+ * $prefs_db_charset (string) allows you to explicitly
+ * set the user preferences (SQL) database connection
+ * character set.  In most cases, system defaults should
+ * be sufficient, even for UTF-8 preference values and
+ * so forth, but this allows you to specifically make
+ * the selection as needed, for example:
+ * $prefs_db_charset = 'utf8mb4';
+ *
  * $use_expiring_security_tokens (boolean) allows you to
  * make SquirrelMail use short-lived anti-CSRF security
  * tokens that expire as desired (not recommended, can
index b1534501168e433e23f0f19d77718ea0ea0fa516..65325ef82dc48b764e87de8d2959d26be706fc07 100644 (file)
  *                                     NOT to quote identifiers by setting
  *                                     this to "none"
  *
+ * If needed, you can also set $prefs_db_charset as a string
+ * (such as "utf8mb4") in config/config_local.php if your system
+ * does not default the SQL connection character set as expected
+ * (most sensible systems will do the right thing transparently).
+ *
  * @copyright 1999-2022 The SquirrelMail Project Team
  * @license http://opensource.org/licenses/gpl-license.php GNU Public License
  * @version $Id$
@@ -245,7 +250,7 @@ class dbPrefs {
      *
      */
     function open() {
-        global $prefs_dsn, $prefs_table, $use_pdo, $db_identifier_quote_char;
+        global $prefs_dsn, $prefs_db_charset, $prefs_table, $use_pdo, $db_identifier_quote_char;
         global $prefs_user_field, $prefs_key_field, $prefs_val_field;
         global $prefs_user_size, $prefs_key_size, $prefs_val_size;
 
@@ -347,6 +352,8 @@ class dbPrefs {
                 $pdo_prefs_dsn = $matches[1] . ':unix_socket=' . $matches[9] . ';dbname=' . $matches[5];
             else
                 $pdo_prefs_dsn = $matches[1] . ':host=' . $matches[4] . (!empty($matches[6]) ? ';port=' . $matches[6] : '') . ';dbname=' . $matches[5];
+            if (!empty($prefs_db_charset))
+               $pdo_prefs_dsn .= ';charset=' . $prefs_db_charset;
             try {
                 $dbh = new PDO($pdo_prefs_dsn, $matches[2], $matches[3]);
             } catch (Exception $e) {
@@ -363,6 +370,31 @@ class dbPrefs {
         }
 
         $this->dbh = $dbh;
+
+        // Older versions of PHP are buggy with setting charset on the dsn so we also issue a SET NAMES
+        if (!empty($prefs_db_charset)) {
+            if ($use_pdo) {
+                $res = $dbh->exec('SET NAMES \'' . $prefs_db_charset . '\'');
+                /* Purposefully not checking for errors; some setups reportedly botch this on queries like this
+                if ($res === FALSE) {
+                    if ($pdo_show_sql_errors)
+                        $this->error = implode(' - ', $sth->errorInfo());
+                    else
+                        $this->error = _("Could not execute query");
+                }
+                $this->failQuery();
+                */
+            }
+            else {
+                $res = $this->dbh->simpleQuery('SET NAMES \'' . $prefs_db_charset . '\'');
+                /* Purposefully not checking for errors; some setups reportedly botch this on queries like this
+                if(DB::isError($res)) {
+                    $this->failQuery($res);
+                }
+                */
+            }
+        }
+
         return true;
     }