From f52e7a00735e3542c049464735cee57bebacdb2f Mon Sep 17 00:00:00 2001
From: alecpl <alec@alec.pl>
Date: Sun, 31 Jan 2010 13:26:59 -0500
Subject: [PATCH] - Fix character set conversion fails on systems where iconv doesn't accept //IGNORE (#1486375)

---
 CHANGELOG                |    1 +
 program/include/main.inc |   37 +++++++++++++++++++++++++++++++++----
 2 files changed, 34 insertions(+), 4 deletions(-)

diff --git a/CHANGELOG b/CHANGELOG
index 144d9d3..9088b4d 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,6 +1,7 @@
 CHANGELOG RoundCube Webmail
 ===========================
 
+- Fix character set conversion fails on systems where iconv doesn't accept //IGNORE (#1486375)
 - Login preformance: Create default folders on first login only
 - Import contacts into the selected address book (by Phil Weir)
 - Add support for MDB2's 'sqlsrv' driver (#1486395)
diff --git a/program/include/main.inc b/program/include/main.inc
index 36d3908..31e4ab5 100644
--- a/program/include/main.inc
+++ b/program/include/main.inc
@@ -170,6 +170,18 @@
 
 
 /**
+ * Catch an error and throw an exception.
+ *
+ * @param  int    Level of the error
+ * @param  string Error message
+ */ 
+function rcube_error_handler($errno, $errstr)
+  {
+  throw new ErrorException($errstr, 0, $errno);
+  }
+
+
+/**
  * Convert a string from one charset to another.
  * Uses mbstring and iconv functions if possible
  *
@@ -180,6 +192,7 @@
  */
 function rcube_charset_convert($str, $from, $to=NULL)
   {
+  static $iconv_options = null;
   static $mbstring_loaded = null;
   static $mbstring_list = null;
   static $convert_warning = false;
@@ -195,20 +208,36 @@
 
   // convert charset using iconv module  
   if (function_exists('iconv') && $from != 'UTF-7' && $to != 'UTF-7') {
-    $_iconv = @iconv($from, $to . '//IGNORE', $str);
+    if ($iconv_options === null) {
+      // transliterate characters not available in output charset
+      $iconv_options = '//TRANSLIT';
+      if (iconv('', $iconv_options, '') === false) {
+        // iconv implementation does not support options
+        $iconv_options = '';
+      }
+    }
+    // throw an exception if iconv reports an illegal character in input
+    // it means that input string has been truncated
+    set_error_handler('rcube_error_handler', E_NOTICE);
+    try {
+      $_iconv = iconv($from, $to . $iconv_options, $str);
+    } catch (ErrorException $e) {
+      $_iconv = false;
+    }
+    restore_error_handler();
     if ($_iconv !== false) {
-        return $_iconv;
+      return $_iconv;
     }
   }
 
-  if (is_null($mbstring_loaded))
+  if ($mbstring_loaded === null)
     $mbstring_loaded = extension_loaded('mbstring');
     
   // convert charset using mbstring module
   if ($mbstring_loaded) {
     $aliases['WINDOWS-1257'] = 'ISO-8859-13';
     
-    if (is_null($mbstring_list)) {
+    if ($mbstring_list === null) {
       $mbstring_list = mb_list_encodings();
       $mbstring_list = array_map('strtoupper', $mbstring_list);
     }

--
Gitblit v1.9.1