# HG changeset patch # User ivan.komarov@soc.pidgin.im # Date 1280334604 0 # Node ID ca90b6c27eb84682e98dd767e23e2c998620d96f # Parent 9d386bf63eab2d44a6adbc5179b495bd06494bd4 Refactored oscar_encoding_to_utf8(). 1. Removed elb's hack from #1645. It doesn't appear to be necessary anymore, since the recent official clients (6.5, 7.1) aren't that stupid now. 2. Simplified logic in incomingim_chan2(). 3. Removed all NULL return check for oscar_encoding_to_utf8(), because it will always return non-NULL value. diff -r 9d386bf63eab -r ca90b6c27eb8 libpurple/protocols/oscar/encoding.c --- a/libpurple/protocols/oscar/encoding.c Tue Jul 27 21:17:01 2010 +0000 +++ b/libpurple/protocols/oscar/encoding.c Wed Jul 28 16:30:04 2010 +0000 @@ -33,70 +33,51 @@ return AIM_CHARSET_ASCII; } -gchar * -oscar_encoding_extract(const char *encoding) +static gchar * +encoding_extract(const char *encoding) { - gchar *ret = NULL; char *begin, *end; g_return_val_if_fail(encoding != NULL, NULL); - /* Make sure encoding begins with charset= */ - if (strncmp(encoding, "text/aolrtf; charset=", 21) && - strncmp(encoding, "text/x-aolrtf; charset=", 23) && - strncmp(encoding, "text/plain; charset=", 20)) - { - return NULL; + if (!g_str_has_prefix(encoding, "text/aolrtf; charset=") && + !g_str_has_prefix(encoding, "text/x-aolrtf; charset=") && + !g_str_has_prefix(encoding, "text/plain; charset=")) { + return g_strdup(encoding); } begin = strchr(encoding, '"'); end = strrchr(encoding, '"'); - if ((begin == NULL) || (end == NULL) || (begin >= end)) - return NULL; + if ((begin == NULL) || (end == NULL) || (begin >= end)) { + return g_strdup(encoding); + } - ret = g_strndup(begin+1, (end-1) - begin); - - return ret; + return g_strndup(begin+1, (end-1) - begin); } gchar * -oscar_encoding_to_utf8(PurpleAccount *account, const char *encoding, const char *text, int textlen) +oscar_encoding_to_utf8(const char *encoding, const char *text, int textlen) { gchar *utf8 = NULL; - - if ((encoding == NULL) || encoding[0] == '\0') { + const gchar *glib_encoding = NULL; + gchar *extracted_encoding = encoding_extract(encoding); + + if (extracted_encoding == NULL || *extracted_encoding == '\0') { purple_debug_info("oscar", "Empty encoding, assuming UTF-8\n"); - } else if (!g_ascii_strcasecmp(encoding, "iso-8859-1")) { - utf8 = g_convert(text, textlen, "UTF-8", "iso-8859-1", NULL, NULL, NULL); - } else if (!g_ascii_strcasecmp(encoding, "ISO-8859-1-Windows-3.1-Latin-1") || - !g_ascii_strcasecmp(encoding, "us-ascii")) - { - utf8 = g_convert(text, textlen, "UTF-8", "Windows-1252", NULL, NULL, NULL); - } else if (!g_ascii_strcasecmp(encoding, "unicode-2-0")) { - /* Some official ICQ clients are apparently total crack, - * and have been known to save a UTF-8 string converted - * from the locale character set to UTF-16 (not from UTF-8 - * to UTF-16!) in the away message. This hack should find - * and do something (un)reasonable with that, and not - * mess up too much else. */ - const gchar *charset = purple_account_get_string(account, "encoding", NULL); - if (charset) { - gsize len; - utf8 = g_convert(text, textlen, charset, "UTF-16BE", &len, NULL, NULL); - if (!utf8 || len != textlen || !g_utf8_validate(utf8, -1, NULL)) { - g_free(utf8); - utf8 = NULL; - } else { - purple_debug_info("oscar", "Used broken ICQ fallback encoding\n"); - } - } - if (!utf8) - utf8 = g_convert(text, textlen, "UTF-8", "UTF-16BE", NULL, NULL, NULL); - } else if (g_ascii_strcasecmp(encoding, "utf-8")) { - purple_debug_warning("oscar", "Unrecognized character encoding \"%s\", " - "attempting to convert to UTF-8 anyway\n", encoding); - utf8 = g_convert(text, textlen, "UTF-8", encoding, NULL, NULL, NULL); + } else if (!g_ascii_strcasecmp(extracted_encoding, "iso-8859-1")) { + glib_encoding = "iso-8859-1"; + } else if (!g_ascii_strcasecmp(extracted_encoding, "ISO-8859-1-Windows-3.1-Latin-1") || !g_ascii_strcasecmp(extracted_encoding, "us-ascii")) { + glib_encoding = "Windows-1252"; + } else if (!g_ascii_strcasecmp(extracted_encoding, "unicode-2-0")) { + glib_encoding = "UTF-16BE"; + } else if (g_ascii_strcasecmp(extracted_encoding, "utf-8")) { + purple_debug_warning("oscar", "Unrecognized character encoding \"%s\", attempting to convert to UTF-8 anyway\n", extracted_encoding); + glib_encoding = extracted_encoding; + } + + if (glib_encoding != NULL) { + utf8 = g_convert(text, textlen, "UTF-8", glib_encoding, NULL, NULL, NULL); } /* @@ -106,13 +87,13 @@ * just copy it. */ if (utf8 == NULL) { - if (textlen != 0 && *text != '\0' - && !g_utf8_validate(text, textlen, NULL)) + if (textlen != 0 && *text != '\0' && !g_utf8_validate(text, textlen, NULL)) utf8 = g_strdup(_("(There was an error receiving this message. The buddy you are speaking with is probably using a different encoding than expected. If you know what encoding he is using, you can specify it in the advanced account options for your AIM/ICQ account.)")); else utf8 = g_strndup(text, textlen); } + g_free(extracted_encoding); return utf8; } diff -r 9d386bf63eab -r ca90b6c27eb8 libpurple/protocols/oscar/encoding.h --- a/libpurple/protocols/oscar/encoding.h Tue Jul 27 21:17:01 2010 +0000 +++ b/libpurple/protocols/oscar/encoding.h Wed Jul 28 16:30:04 2010 +0000 @@ -29,14 +29,7 @@ */ guint16 oscar_charset_check(const char *utf8); -/** - * Take a string of the form charset="bleh" where bleh is - * one of us-ascii, utf-8, iso-8859-1, or unicode-2-0, and - * return a newly allocated string containing bleh. - */ -gchar * oscar_encoding_extract(const char *encoding); - -gchar * oscar_encoding_to_utf8(PurpleAccount *account, const char *encoding, const char *text, int textlen); +gchar * oscar_encoding_to_utf8(const char *encoding, const char *text, int textlen); gchar * oscar_utf8_try_convert(PurpleAccount *account, OscarData *od, const gchar *msg); /** diff -r 9d386bf63eab -r ca90b6c27eb8 libpurple/protocols/oscar/oscar.c --- a/libpurple/protocols/oscar/oscar.c Tue Jul 27 21:17:01 2010 +0000 +++ b/libpurple/protocols/oscar/oscar.c Wed Jul 28 16:30:04 2010 +0000 @@ -1413,18 +1413,18 @@ purple_prpl_got_user_status_deactive(account, info->bn, OSCAR_STATUS_ID_MOBILE); } - if (info->status != NULL && info->status[0] != '\0') + if (info->status != NULL && info->status[0] != '\0') { /* Grab the available message */ - message = oscar_encoding_to_utf8(account, info->status_encoding, - info->status, info->status_len); + message = oscar_encoding_to_utf8(info->status_encoding, info->status, info->status_len); + } tmp2 = tmp = (message ? purple_markup_escape_text(message, -1) : NULL); if (strcmp(status_id, OSCAR_STATUS_ID_AVAILABLE) == 0) { - if (info->itmsurl_encoding && info->itmsurl && info->itmsurl_len) + if (info->itmsurl_encoding && info->itmsurl && info->itmsurl_len) { /* Grab the iTunes Music Store URL */ - itmsurl = oscar_encoding_to_utf8(account, info->itmsurl_encoding, - info->itmsurl, info->itmsurl_len); + itmsurl = oscar_encoding_to_utf8(info->itmsurl_encoding, info->itmsurl, info->itmsurl_len); + } if (tmp2 == NULL && itmsurl != NULL) /* @@ -1705,35 +1705,20 @@ G_GUINT64_FORMAT ", user %s, status %hu\n", args->type, userinfo->bn, args->status); - if (args->msg != NULL) - { - if (args->encoding != NULL) - { - char *encoding = NULL; - encoding = oscar_encoding_extract(args->encoding); - message = oscar_encoding_to_utf8(account, encoding, args->msg, - args->msglen); - g_free(encoding); - } else { - if (g_utf8_validate(args->msg, args->msglen, NULL)) - message = g_strdup(args->msg); - } + if (args->msg != NULL) { + message = oscar_encoding_to_utf8(args->encoding, args->msg, args->msglen); } if (args->type & OSCAR_CAPABILITY_CHAT) { - char *encoding, *utf8name, *tmp; + char *utf8name, *tmp; GHashTable *components; if (!args->info.chat.roominfo.name || !args->info.chat.roominfo.exchange) { g_free(message); return 1; } - encoding = args->encoding ? oscar_encoding_extract(args->encoding) : NULL; - utf8name = oscar_encoding_to_utf8(account, encoding, - args->info.chat.roominfo.name, - args->info.chat.roominfo.namelen); - g_free(encoding); + utf8name = oscar_encoding_to_utf8(args->encoding, args->info.chat.roominfo.name, args->info.chat.roominfo.namelen); tmp = extract_name(utf8name); if (tmp != NULL) @@ -1754,8 +1739,7 @@ components); } - else if ((args->type & OSCAR_CAPABILITY_SENDFILE) || - (args->type & OSCAR_CAPABILITY_DIRECTIM)) + else if ((args->type & OSCAR_CAPABILITY_SENDFILE) || (args->type & OSCAR_CAPABILITY_DIRECTIM)) { if (args->status == AIM_RENDEZVOUS_PROPOSE) { @@ -1808,24 +1792,11 @@ purple_debug_info("oscar", "Got an ICQ Server Relay message of " "type %d\n", args->info.rtfmsg.msgtype); - if (args->info.rtfmsg.msgtype == 1) - { - if (args->info.rtfmsg.msg != NULL) - { - char *rtfmsg = NULL; - if (args->encoding != NULL) { - char *encoding = oscar_encoding_extract(args->encoding); - rtfmsg = oscar_encoding_to_utf8(account, encoding, - args->info.rtfmsg.msg, strlen(args->info.rtfmsg.msg)); - g_free(encoding); - } else { - if (g_utf8_validate(args->info.rtfmsg.msg, strlen(args->info.rtfmsg.msg), NULL)) - rtfmsg = g_strdup(args->info.rtfmsg.msg); - } - if (rtfmsg) { - serv_got_im(gc, userinfo->bn, rtfmsg, flags, time(NULL)); - g_free(rtfmsg); - } + if (args->info.rtfmsg.msgtype == 1) { + if (args->info.rtfmsg.msg != NULL) { + char *rtfmsg = oscar_encoding_to_utf8(args->encoding, args->info.rtfmsg.msg, strlen(args->info.rtfmsg.msg)); + serv_got_im(gc, userinfo->bn, rtfmsg, flags, time(NULL)); + g_free(rtfmsg); } } else if (args->info.rtfmsg.msgtype == 26) { purple_debug_info("oscar", "Sending X-Status Reply\n"); @@ -2582,7 +2553,6 @@ static int purple_conv_chat_incoming_msg(OscarData *od, FlapConnection *conn, FlapFrame *fr, ...) { PurpleConnection *gc = od->gc; - PurpleAccount *account = purple_connection_get_account(gc); struct chat_connection *ccon = find_oscar_chat_by_conn(gc, conn); gchar *utf8; va_list ap; @@ -2601,10 +2571,7 @@ charset = va_arg(ap, char *); va_end(ap); - utf8 = oscar_encoding_to_utf8(account, charset, msg, len); - if (utf8 == NULL) - /* The conversion failed! */ - utf8 = g_strdup(_("[Unable to display a message from this user because it contained invalid characters.]")); + utf8 = oscar_encoding_to_utf8(charset, msg, len); serv_got_chat_in(gc, ccon->id, info->bn, 0, utf8, time(NULL)); g_free(utf8); diff -r 9d386bf63eab -r ca90b6c27eb8 libpurple/protocols/oscar/userinfo.c --- a/libpurple/protocols/oscar/userinfo.c Tue Jul 27 21:17:01 2010 +0000 +++ b/libpurple/protocols/oscar/userinfo.c Wed Jul 28 16:30:04 2010 +0000 @@ -191,30 +191,21 @@ the "message" attribute of the status contains only the plaintext message. */ if (userinfo) { - if ((userinfo->flags & AIM_FLAG_AWAY) - && userinfo->away_len > 0 - && userinfo->away != NULL - && userinfo->away_encoding != NULL) - { + if ((userinfo->flags & AIM_FLAG_AWAY) && userinfo->away_len > 0 && userinfo->away != NULL && userinfo->away_encoding != NULL) { /* Away message */ - tmp = oscar_encoding_extract(userinfo->away_encoding); - message = oscar_encoding_to_utf8(account, - tmp, userinfo->away, userinfo->away_len); - g_free(tmp); + message = oscar_encoding_to_utf8(userinfo->away_encoding, userinfo->away, userinfo->away_len); } else { /* * Available message or non-HTML away message (because that's * all we have right now. */ if ((userinfo->status != NULL) && userinfo->status[0] != '\0') { - message = oscar_encoding_to_utf8(account, - userinfo->status_encoding, userinfo->status, - userinfo->status_len); + message = oscar_encoding_to_utf8(userinfo->status_encoding, userinfo->status, userinfo->status_len); } #if defined (_WIN32) || defined (__APPLE__) - if (userinfo->itmsurl && (userinfo->itmsurl[0] != '\0')) - itmsurl = oscar_encoding_to_utf8(account, userinfo->itmsurl_encoding, - userinfo->itmsurl, userinfo->itmsurl_len); + if (userinfo->itmsurl && (userinfo->itmsurl[0] != '\0')) { + itmsurl = oscar_encoding_to_utf8(userinfo->itmsurl_encoding, userinfo->itmsurl, userinfo->itmsurl_len); + } #endif } } else { @@ -552,17 +543,12 @@ /* Info */ if ((userinfo->info_len > 0) && (userinfo->info != NULL) && (userinfo->info_encoding != NULL)) { - tmp = oscar_encoding_extract(userinfo->info_encoding); - info_utf8 = oscar_encoding_to_utf8(account, tmp, userinfo->info, - userinfo->info_len); + info_utf8 = oscar_encoding_to_utf8(userinfo->info_encoding, userinfo->info, userinfo->info_len); + tmp = oscar_util_format_string(info_utf8, purple_account_get_username(account)); + purple_notify_user_info_add_section_break(user_info); + oscar_user_info_add_pair(user_info, _("Profile"), tmp); g_free(tmp); - if (info_utf8 != NULL) { - tmp = oscar_util_format_string(info_utf8, purple_account_get_username(account)); - purple_notify_user_info_add_section_break(user_info); - oscar_user_info_add_pair(user_info, _("Profile"), tmp); - g_free(tmp); - g_free(info_utf8); - } + g_free(info_utf8); } purple_notify_user_info_add_section_break(user_info);