diff src/util.c @ 7820:8e60ddc28a22

[gaim-migrate @ 8472] Mostly I just made the whole i18n-mime-email receiving thing for MSN work without crashing. I did this by rewriting gaim_mime_decode_field() It's not what you would call "efficient," but I mean, it only gets called when you get new mail notificaion on MSN. I think it's a lot easier to follow than revo/shx's version. Hopefully that's not because I left out some critical element. http://kingant.net/oscar/gaim/neat.png committer: Tailor Script <tailor@pidgin.im>
author Mark Doliner <mark@kingant.net>
date Tue, 09 Dec 2003 16:12:24 +0000
parents 622c9149609c
children 1663c076a744
line wrap: on
line diff
--- a/src/util.c	Tue Dec 09 03:07:29 2003 +0000
+++ b/src/util.c	Tue Dec 09 16:12:24 2003 +0000
@@ -281,13 +281,15 @@
  **************************************************************************/
 #define OUT_CHARSET "utf-8"
 
-char *
+static char *
 gaim_mime_decode_word(const char *charset, const char *encoding, const char *str)
 {
-	/* TODO: We need to check for nulls */
 	char *decoded, *converted;
 	int len = 0;
 
+	if ((charset == NULL) || (encoding == NULL) || (str == NULL))
+		return NULL;
+
 	if (g_ascii_strcasecmp(encoding, "Q") == 0)
 		gaim_quotedp_decode(str, &decoded, &len);
 	else if (g_ascii_strcasecmp(encoding, "B") == 0)
@@ -304,6 +306,57 @@
 char *
 gaim_mime_decode_field(const char *str)
 {
+	GString *donedeal;
+	char *orig, *start, *end, *end_of_last, *tmp;
+	char **encoded_word;
+	char *charset, *encoding, *word;
+
+	g_return_val_if_fail(str != NULL, NULL);
+
+	orig = g_strdup(str);
+	donedeal = g_string_sized_new(strlen(orig));
+
+	/* One iteration per encoded-word */
+	end_of_last = orig;
+	while ((start = strstr(end_of_last, "=?")) && (end = strstr(start, "?="))) {
+		/* Append everything from the end of the last encoded-word to the beginning of the next */
+		tmp = g_strndup(end_of_last, (start - end_of_last));
+		donedeal = g_string_append(donedeal, tmp);
+		g_free(tmp);
+
+		/* Split the encoded word */
+		tmp = g_strndup(start + 2, end - start - 4);
+		encoded_word = g_strsplit(tmp, "?", 3);
+		g_free(tmp);
+		charset = encoded_word[0];
+		encoding = charset != NULL ? encoded_word[1] : NULL;
+		word = encoding != NULL ? encoded_word[2] : NULL;
+		g_strfreev(encoded_word);
+
+		/* Convert the decoded word to utf8 and append it */
+		tmp = gaim_mime_decode_word(charset, encoding, word);
+		donedeal = g_string_append(donedeal, tmp);
+		g_free(tmp);
+
+		g_free(charset);
+		g_free(encoding);
+		g_free(word);
+	}
+
+	/* Append everything from the end of the last encoded-word to the end of the string */
+	tmp = g_strndup(end_of_last, ((orig + strlen(orig)) - end_of_last));
+	donedeal = g_string_append(donedeal, tmp);
+	g_free(tmp);
+
+	/* Free at last, free at last... */
+	tmp = donedeal->str;
+	g_string_free(donedeal, FALSE);
+	g_free(orig);
+
+	return tmp;
+
+#if 0
+	/* This is revo/shx's version, and it caused coredumps for me */
 	char *cur, *mark;
 	char *unencoded_start, *unencoded_end;
 	char *charset, *encoding, *word, *decoded;
@@ -312,13 +365,14 @@
 	n = new = g_malloc(strlen(str));
 	charset = word = NULL;
 
+gaim_debug(GAIM_DEBUG_ERROR, "XXX", "new is %d\n", new);
 	/* Here we will be looking for encoded words and if they seem to be
 	 * valid then decode them */
 
-	for (	unencoded_start = cur = (char *)str;
-			(unencoded_end = cur = strstr(cur, "=?"));
-			unencoded_start = cur)
-	{
+	for (unencoded_start = cur = str;
+		 (unencoded_end = cur = strstr(cur, "=?"));
+		 unencoded_start = cur)	{
+
 		int len;
 		char *token;
 		GQueue *tokens = g_queue_new();
@@ -343,6 +397,7 @@
 		}
 
 		cur += 2;
+gaim_debug(GAIM_DEBUG_ERROR, "XXX", "new is %d, this is probably different than above, that's bad\n", new);
 
 		if ((tokens->length == 3) && (*mark == '=')) {
 			len = unencoded_end - unencoded_start;
@@ -378,6 +433,7 @@
 		n = strcpy(n, unencoded_start);
 
 	return new;
+#endif
 }
 
 /**************************************************************************