Index: pidgin-2.6.6/libpurple/protocols/msn/oim.c
===================================================================
--- pidgin-2.6.6.orig/libpurple/protocols/msn/oim.c
+++ pidgin-2.6.6/libpurple/protocols/msn/oim.c
@@ -23,7 +23,10 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,  USA
  */
-#include "msn.h"
+
+#include "internal.h"
+#include "debug.h"
+
 #include "soap.h"
 #include "oim.h"
 #include "msnutils.h"
@@ -163,20 +166,17 @@ msn_oim_request_cb(MsnSoapMessage *reque
 	xmlnode *fault = NULL;
 	xmlnode *faultcode = NULL;
 
-	if (response == NULL)
-		return;
-
-	fault = xmlnode_get_child(response->xml, "Body/Fault");
-	if (fault)
-		faultcode = xmlnode_get_child(fault, "faultcode");
+	if (response != NULL)
+		fault = xmlnode_get_child(response->xml, "Body/Fault");
 
-	if (faultcode) {
+	if (fault && (faultcode = xmlnode_get_child(fault, "faultcode"))) {
 		gchar *faultcode_str = xmlnode_get_data(faultcode);
 		gboolean need_token_update = FALSE;
 
 		if (faultcode_str) {
 			if (g_str_equal(faultcode_str, "q0:BadContextToken") ||
-				g_str_equal(faultcode_str, "AuthenticationFailed"))
+				g_str_equal(faultcode_str, "AuthenticationFailed") ||
+				g_str_equal(faultcode_str, "s:AuthenticationFailed"))
 				need_token_update = TRUE;
 			else if (g_str_equal(faultcode_str, "q0:AuthenticationFailed") &&
 				xmlnode_get_child(fault, "detail/RequiredAuthPolicy") != NULL)
@@ -419,8 +419,8 @@ msn_oim_send_read_cb(MsnSoapMessage *req
 						str_reason = _("Message was not sent because an unknown "
 						               "error occurred.");
 					}
-					
-					msn_session_report_user(oim->session, msg->to_member, 
+
+					msn_session_report_user(oim->session, msg->to_member,
 						str_reason, PURPLE_MESSAGE_ERROR);
 					msn_session_report_user(oim->session, msg->to_member,
 						msg->oim_msg, PURPLE_MESSAGE_RAW);
@@ -606,11 +606,12 @@ msn_oim_report_to_user(MsnOimRecvData *r
 	const char *date;
 	const char *from;
 	const char *boundary;
-	char *decode_msg = NULL;
+	char *decode_msg = NULL, *clean_msg = NULL;
 	gsize body_len;
 	char **tokens;
 	char *passport = NULL;
 	time_t stamp;
+	const char *charset = NULL;
 
 	message = msn_message_new(MSN_MSG_UNKNOWN);
 
@@ -638,10 +639,12 @@ msn_oim_report_to_user(MsnOimRecvData *r
 			type = msn_message_get_content_type(multipart);
 			if (type && !strcmp(type, "text/plain")) {
 				decode_msg = (char *)purple_base64_decode(multipart->body, &body_len);
-				msn_message_destroy(multipart);
+				charset = msn_message_get_charset(multipart);
+
+				msn_message_unref(multipart);
 				break;
 			}
-			msn_message_destroy(multipart);
+			msn_message_unref(multipart);
 		}
 
 		g_strfreev(tokens);
@@ -649,11 +652,51 @@ msn_oim_report_to_user(MsnOimRecvData *r
 
 		if (decode_msg == NULL) {
 			purple_debug_error("msn", "Couldn't find text/plain OIM message.\n");
-			msn_message_destroy(message);
+			msn_message_unref(message);
 			return;
 		}
 	} else {
 		decode_msg = (char *)purple_base64_decode(message->body, &body_len);
+		charset = msn_message_get_charset(message);
+	}
+
+	if (charset && !((strncasecmp(charset, "UTF-8", 5) == 0) || (strncasecmp(charset, "UTF8", 4) == 0))) {
+		clean_msg = g_convert(decode_msg, body_len, "UTF-8", charset, NULL, NULL, NULL);
+
+		if (!clean_msg) {
+			char *clean = purple_utf8_salvage(decode_msg);
+
+			purple_debug_error("msn", "Failed to convert charset from %s to UTF-8 for OIM message: %s\n", charset, clean);
+
+			clean_msg = g_strdup_printf(_("%s (There was an error receiving this message. "
+			                              "Converting the encoding from %s to UTF-8 failed.)"),
+			                            clean, charset);
+			g_free(clean);
+		}
+
+		g_free(decode_msg);
+
+	} else if (!g_utf8_validate(decode_msg, body_len, NULL)) {
+		char *clean = purple_utf8_salvage(decode_msg);
+
+		purple_debug_error("msn", "Received an OIM message that is not UTF-8,"
+		                          " and no encoding specified: %s\n", clean);
+
+		if (charset) {
+			clean_msg = g_strdup_printf(_("%s (There was an error receiving this message."
+			                              " The charset was %s, but it was not valid UTF-8.)"),
+			                            clean, charset);
+		} else {
+			clean_msg = g_strdup_printf(_("%s (There was an error receiving this message."
+			                              " The charset was missing, but it was not valid UTF-8.)"),
+			                            clean);
+		}
+
+		g_free(clean);
+		g_free(decode_msg);
+
+	} else {
+		clean_msg = decode_msg;
 	}
 
 	from = msn_message_get_attr(message, "X-OIM-originatingSource");
@@ -695,7 +738,7 @@ msn_oim_report_to_user(MsnOimRecvData *r
 	purple_debug_info("msn", "oim Date:{%s},passport{%s}\n",
 	                  date, passport);
 
-	serv_got_im(rdata->oim->session->account->gc, passport, decode_msg, 0,
+	serv_got_im(purple_account_get_connection(rdata->oim->session->account), passport, clean_msg, 0,
 	            stamp);
 
 	/*Now get the oim message ID from the oim_list.
@@ -704,8 +747,8 @@ msn_oim_report_to_user(MsnOimRecvData *r
 	msn_oim_post_delete_msg(rdata);
 
 	g_free(passport);
-	g_free(decode_msg);
-	msn_message_destroy(message);
+	g_free(clean_msg);
+	msn_message_unref(message);
 }
 
 /* Parse the XML data,
@@ -785,7 +828,7 @@ msn_parse_oim_xml(MsnOim *oim, xmlnode *
 
 		/* XXX/khc: pretty sure this is wrong */
 		if (count > 0)
-			purple_notify_emails(session->account->gc, count, FALSE, NULL,
+			purple_notify_emails(purple_account_get_connection(session->account), count, FALSE, NULL,
 				NULL, passports, urls, NULL, NULL);
 		g_free(unread);
 	}
