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) {