From cdb1af046fe7c95a8a9db14c256cdfcf9ecace2b Mon Sep 17 00:00:00 2001 From: djcb Date: Sat, 7 Sep 2013 18:39:00 +0300 Subject: [PATCH] * fix the mu_util_fputs_encoded/bsd heisenbug it seems g_locale_from_utf8 behaves a bit differently on bsd/macosx, causing a segfault (but when run under gdb!). this code path was hit for messages with encoding problems in non-utf8 locales --- lib/mu-util.c | 46 ++++++++++++++++++++-------------------------- 1 file changed, 20 insertions(+), 26 deletions(-) diff --git a/lib/mu-util.c b/lib/mu-util.c index 295593b2..842b1449 100644 --- a/lib/mu-util.c +++ b/lib/mu-util.c @@ -434,41 +434,35 @@ gboolean mu_util_fputs_encoded (const char *str, FILE *stream) { int rv; + unsigned bytes; + char *conv; g_return_val_if_fail (str, FALSE); g_return_val_if_fail (stream, FALSE); /* g_get_charset return TRUE when the locale is UTF8 */ if (mu_util_locale_is_utf8()) - rv = fputs (str, stream); - else { /* charset is _not_ utf8, so we actually have to - * convert it..*/ + return fputs (str, stream) == EOF ? FALSE : TRUE; - GError *err; - unsigned bytes; - char *conv; + /* charset is _not_ utf8, so we actually have to convert + * it + */ + conv = NULL; + if (g_utf8_validate (str, -1, NULL)) + /* it _seems_ that on the bsds, the final err param + * may receive garbage... so we don't use it */ + conv = g_locale_from_utf8 + (str, -1, (gsize*)&bytes, NULL, NULL); - err = NULL; - conv = g_locale_from_utf8 (str, -1, (gsize*)&bytes, NULL, &err); + /* conversion failed; this happens because is some cases GMime + * may gives us non-UTF-8 strings from e.g. wrongly encoded + * message-subjects; if so, we escape the string + */ + if (!conv) + conv = g_strescape (str, "\n\t"); - if (!conv || err) { - /* conversion failed; this happens because is - * some cases GMime may gives us non-UTF-8 - * strings from e.g. wrongly encoded - * message-subjects; if so, we escape the - * string */ - g_warning ("%s: g_locale_from_utf8 failed: %s", - __FUNCTION__, - err ? err->message : "conversion failed"); - g_free (conv); - conv = g_strescape (str, NULL); - g_clear_error (&err); - } - - rv = conv ? fputs (conv, stream) : EOF; - g_free (conv); - - } + rv = conv ? fputs (conv, stream) : EOF; + g_free (conv); return (rv == EOF) ? FALSE : TRUE; }