Attached you can find a compile-tested backported fix for the Evolution
version in Sarge.

Cheers,
        Moritz
diff -Naur evolution-2.0.4.orig/camel/camel-charset-map.c 
evolution-2.0.4/camel/camel-charset-map.c
--- evolution-2.0.4.orig/camel/camel-charset-map.c      2004-12-06 
08:46:50.000000000 +0100
+++ evolution-2.0.4/camel/camel-charset-map.c   2005-04-22 14:38:28.000000000 
+0200
@@ -200,19 +200,18 @@
 
 #else
 
-#include "camel-charset-map.h"
-#include "camel-charset-map-private.h"
-
-#include <gal/util/e-iconv.h>
-
 #include <glib.h>
 #include <locale.h>
-#include <ctype.h>
-#include <pthread.h>
 #ifdef HAVE_CODESET
 #include <langinfo.h>
 #endif
 
+#include "camel-charset-map.h"
+#include "camel-charset-map-private.h"
+#include "camel-utf8.h"
+
+#include <gal/util/e-iconv.h>
+
 void
 camel_charset_init (CamelCharset *c)
 {
@@ -221,42 +220,34 @@
 }
 
 void
-camel_charset_step (CamelCharset *c, const char *in, int len)
+camel_charset_step (CamelCharset *cc, const char *in, int len)
 {
        register unsigned int mask;
        register int level;
-       const char *inptr = in, *inend = in+len;
+       const unsigned char *inptr = in, *inend = in+len;
+       register guint32 c;
 
-       mask = c->mask;
-       level = c->level;
+       mask = cc->mask;
+       level = cc->level;
 
        /* check what charset a given string will fit in */
-       while (inptr < inend) {
-               gunichar c;
-               const char *newinptr;
-               newinptr = g_utf8_next_char(inptr);
-               c = g_utf8_get_char(inptr);
-               if (newinptr == NULL || !g_unichar_validate (c)) {
-                       inptr++;
-                       continue;
-               }
-
-               inptr = newinptr;
-               if (c<=0xffff) {
+       while ( (c = camel_utf8_getc_limit(&inptr, inend)) != 0xffff) {
+               if (c < 0xffff) {
                        mask &= charset_mask(c);
                
                        if (c>=128 && c<256)
                                level = MAX(level, 1);
                        else if (c>=256)
-                               level = MAX(level, 2);
+                               level = 2;
                } else {
                        mask = 0;
-                       level = MAX(level, 2);
+                       level = 2;
+                       break;
                }
        }
 
-       c->mask = mask;
-       c->level = level;
+       cc->mask = mask;
+       cc->level = level;
 }
 
 /* gets the best charset from the mask of chars in it */
diff -Naur evolution-2.0.4.orig/camel/camel-mime-utils.c 
evolution-2.0.4/camel/camel-mime-utils.c
--- evolution-2.0.4.orig/camel/camel-mime-utils.c       2005-02-14 
17:09:04.000000000 +0100
+++ evolution-2.0.4/camel/camel-mime-utils.c    2005-04-22 13:40:59.000000000 
+0200
@@ -2998,44 +2998,24 @@
        const unsigned char *inptr = in;
        unsigned char *outbuf = NULL;
        const char *charset;
-       int encoding;
        GString *out;
        guint32 c;
 
        *encoded = FALSE;
        
        g_return_val_if_fail (in != NULL, NULL);
-       
-       /* do a quick us-ascii check (the common case?) */
-       while (*inptr) {
-               if (*inptr > 127)
-                       break;
-               inptr++;
-       }
-       
-       if (*inptr == '\0')
-               return g_strdup (in);
-       
-       inptr = in;
-       encoding = 0;
-       while ( encoding !=2 && (c = camel_utf8_getc(&inptr)) ) {
-               if (c > 127 && c < 256)
-                       encoding = MAX (encoding, 1);
-               else if (c >= 256)
-                       encoding = MAX (encoding, 2);
-       }
 
-       if (encoding == 2)
-               charset = camel_charset_best(in, strlen(in));
-       else
-               charset = "iso-8859-1";
+       /* if we have really broken utf8 passed in, we just treat it as binary 
data */
+
+       charset = camel_charset_best(in, strlen(in));
+       if (charset == NULL)
+               return g_strdup(in);
        
-       if (strcasecmp(charset, "UTF-8") != 0
-           && (outbuf = header_convert(charset, "UTF-8", in, strlen(in)))) {
-               inptr = outbuf;
-       } else {
-               charset = "UTF-8";
-               inptr = in;
+       if (g_ascii_strcasecmp(charset, "UTF-8") != 0) {
+               if ((outbuf = header_convert(charset, "UTF-8", in, strlen(in))))
+                       inptr = outbuf;
+               else
+                       return g_strdup(in);
        }
        
        /* FIXME: set the 'language' as well, assuming we can get that info...? 
*/
diff -Naur evolution-2.0.4.orig/camel/tests/misc/test2.c 
evolution-2.0.4/camel/tests/misc/test2.c
--- evolution-2.0.4.orig/camel/tests/misc/test2.c       2004-06-01 
12:07:13.000000000 +0200
+++ evolution-2.0.4/camel/tests/misc/test2.c    2005-04-22 13:50:58.000000000 
+0200
@@ -53,7 +53,7 @@
        { 1,
          { "name", 
"Doul\xC3\xADk01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123457890123456789123456789"
 },
          ";\n"
-         
"\tname*0*=iso-8859-1''Doul%EDk012345678901234567890123456789012345678901234;\n"
+         
"\tname*0*=ISO-8859-1''Doul%EDk012345678901234567890123456789012345678901234;\n"
          
"\tname*1*=56789012345678901234567890123456789012345678901234567890123457890;\n"
          "\tname*2*=123456789123456789" },
        { 1,
@@ -61,7 +61,7 @@
          "; name=\"\\\"%$#@ special chars?;; !\"" },
        { 1,
          { "name", "\"%$#@ special chars?;; !\xC3\xAD" },
-         "; name*=iso-8859-1''%22%25$#%40%20special%20chars%3F%3B%3B%20!%ED" },
+         "; name*=ISO-8859-1''%22%25$#%40%20special%20chars%3F%3B%3B%20!%ED" },
 };
 
 int
diff -Naur evolution-2.0.4.orig/mail/em-inline-filter.c 
evolution-2.0.4/mail/em-inline-filter.c
--- evolution-2.0.4.orig/mail/em-inline-filter.c        2004-05-19 
09:02:12.000000000 +0200
+++ evolution-2.0.4/mail/em-inline-filter.c     2005-04-22 13:50:36.000000000 
+0200
@@ -196,6 +196,7 @@
                        if (strncmp(start, "begin ", 6) == 0
                            && start[6] >= '0' && start[6] <= '7') {
                                int i = 7;
+                               char *name;
 
                                while (start[i] >='0' && start[i] <='7')
                                        i++;
@@ -206,7 +207,10 @@
                                        break;
 
                                emif_add_part(emif, data_start, 
start-data_start);
-                               emif->filename = g_strndup(start+i, 
inptr-start-i-1);
+
+                               name = g_strndup(start+i, inptr-start-i-1);
+                               emif->filename = 
camel_header_decode_string(name, 
emif->base_type?camel_content_type_param(emif->base_type, "charset"):NULL);
+                               g_free(name);
                                data_start = start;
                                emif->state = EMIF_UUENC;
                        } else if (strncmp(start, "(This file must be converted 
with BinHex 4.0)", 45) == 0) {

Reply via email to