comparison libpurple/protocols/oscar/encoding.c @ 31417:52801bade70e

Currently oscar (ICQ) protocol does not support comma-separated list of encoding, what may cause problems with clients that using single-byte encoding, while we using UTF-8 (for example: QIP2005). This patch adds support for a comma-separated list of encodings. for example: {{{ utf-8,cp1251,us-ascii }}} This patch also fixes invalid encoding of buddy status and buddy info. Fixes #13496. committer: John Bailey <rekkanoryo@rekkanoryo.org>
author loentar@google.com
date Thu, 24 Mar 2011 22:37:29 +0000
parents a8cc50c2279f
children
comparison
equal deleted inserted replaced
31416:e2c016bb436f 31417:52801bade70e
19 */ 19 */
20 20
21 #include "encoding.h" 21 #include "encoding.h"
22 22
23 static gchar * 23 static gchar *
24 encoding_multi_convert_to_utf8(const gchar *text, gssize textlen, const gchar *encodings, GError **error, gboolean fallback)
25 {
26 gchar *utf8 = NULL;
27 const gchar *begin = encodings;
28 const gchar *end = NULL;
29 gchar *curr_encoding = NULL; /* allocated buffer for encoding name */
30 const gchar *curr_encoding_ro = NULL; /* read-only encoding name */
31
32 if (!encodings) {
33 purple_debug_error("oscar", "encodings is NULL");
34 return NULL;
35 }
36
37 for (;;)
38 {
39 /* extract next encoding */
40 end = strchr(begin, ',');
41 if (!end) {
42 curr_encoding_ro = begin;
43 } else { /* allocate buffer for encoding */
44 curr_encoding = g_strndup(begin, end - begin);
45 if (!curr_encoding) {
46 purple_debug_error("oscar", "Error allocating memory for encoding");
47 break;
48 }
49 curr_encoding_ro = curr_encoding;
50 }
51
52 if (!g_ascii_strcasecmp(curr_encoding_ro, "utf-8") && g_utf8_validate(text, textlen, NULL)) {
53 break;
54 }
55
56 utf8 = g_convert(text, textlen, "UTF-8", curr_encoding_ro, NULL, NULL, NULL);
57
58 if (!end) /* last occurence. do not free curr_encoding: buffer was'nt allocated */
59 break;
60
61 g_free(curr_encoding); /* free allocated buffer for encoding here */
62
63 if (utf8) /* text was successfully converted */
64 break;
65
66 begin = end + 1;
67 }
68
69 if (!utf8 && fallback)
70 { /* "begin" points to last encoding */
71 utf8 = g_convert_with_fallback(text, textlen, "UTF-8", begin, "?", NULL, NULL, error);
72 }
73
74 return utf8;
75 }
76
77 static gchar *
24 encoding_extract(const char *encoding) 78 encoding_extract(const char *encoding)
25 { 79 {
26 char *begin, *end; 80 char *begin, *end;
27 81
28 if (encoding == NULL) { 82 if (encoding == NULL) {
63 } else if (g_ascii_strcasecmp(extracted_encoding, "utf-8")) { 117 } else if (g_ascii_strcasecmp(extracted_encoding, "utf-8")) {
64 glib_encoding = extracted_encoding; 118 glib_encoding = extracted_encoding;
65 } 119 }
66 120
67 if (glib_encoding != NULL) { 121 if (glib_encoding != NULL) {
68 utf8 = g_convert(text, textlen, "UTF-8", glib_encoding, NULL, NULL, NULL); 122 utf8 = encoding_multi_convert_to_utf8(text, textlen, glib_encoding, NULL, FALSE);
69 } 123 }
70 124
71 /* 125 /*
72 * If utf8 is still NULL then either the encoding is utf-8 or 126 * If utf8 is still NULL then either the encoding is utf-8 or
73 * we have been unable to convert the text to utf-8 from the encoding 127 * we have been unable to convert the text to utf-8 from the encoding
99 153
100 if (od->icq) 154 if (od->icq)
101 charset = purple_account_get_string(account, "encoding", NULL); 155 charset = purple_account_get_string(account, "encoding", NULL);
102 156
103 if(charset && *charset) 157 if(charset && *charset)
104 ret = g_convert(msg, -1, "UTF-8", charset, NULL, NULL, NULL); 158 ret = encoding_multi_convert_to_utf8(msg, -1, charset, NULL, FALSE);
105 159
106 if(!ret) 160 if(!ret)
107 ret = purple_utf8_try_convert(msg); 161 ret = purple_utf8_try_convert(msg);
108 162
109 return ret; 163 return ret;
117 171
118 if ((charsetstr == NULL) || (*charsetstr == '\0')) 172 if ((charsetstr == NULL) || (*charsetstr == '\0'))
119 return NULL; 173 return NULL;
120 174
121 if (g_ascii_strcasecmp("UTF-8", charsetstr)) { 175 if (g_ascii_strcasecmp("UTF-8", charsetstr)) {
122 if (fallback) 176 ret = encoding_multi_convert_to_utf8(data, datalen, charsetstr, &err, fallback);
123 ret = g_convert_with_fallback(data, datalen, "UTF-8", charsetstr, "?", NULL, NULL, &err);
124 else
125 ret = g_convert(data, datalen, "UTF-8", charsetstr, NULL, NULL, &err);
126 if (err != NULL) { 177 if (err != NULL) {
127 purple_debug_warning("oscar", "Conversion from %s failed: %s.\n", 178 purple_debug_warning("oscar", "Conversion from %s failed: %s.\n",
128 charsetstr, err->message); 179 charsetstr, err->message);
129 g_error_free(err); 180 g_error_free(err);
130 } 181 }