Mercurial > pidgin
comparison src/util.c @ 11127:719779387f96
[gaim-migrate @ 13183]
Change the base16 and base64 functions to use better data types,
and make appropriate changes to other parts of the Gaim code
to get rid of a few warnings and hopefully make things more
correct.
In other news, why is CVS HEAD crashing for me on exit?
committer: Tailor Script <tailor@pidgin.im>
author | Mark Doliner <mark@kingant.net> |
---|---|
date | Tue, 19 Jul 2005 05:15:45 +0000 |
parents | a8a7730db73c |
children | a4611130e3eb |
comparison
equal
deleted
inserted
replaced
11126:2a3568cbd8a6 | 11127:719779387f96 |
---|---|
65 static char home_dir[MAXPATHLEN]; | 65 static char home_dir[MAXPATHLEN]; |
66 | 66 |
67 /************************************************************************** | 67 /************************************************************************** |
68 * Base16 Functions | 68 * Base16 Functions |
69 **************************************************************************/ | 69 **************************************************************************/ |
70 unsigned char * | 70 gchar * |
71 gaim_base16_encode(const unsigned char *data, int length) | 71 gaim_base16_encode(const guint8 *data, gsize len) |
72 { | 72 { |
73 int i; | 73 int i; |
74 unsigned char *ascii = NULL; | 74 gchar *ascii = NULL; |
75 | 75 |
76 g_return_val_if_fail(data != NULL, NULL); | 76 g_return_val_if_fail(data != NULL, NULL); |
77 g_return_val_if_fail(length > 0, NULL); | 77 g_return_val_if_fail(len > 0, NULL); |
78 | 78 |
79 ascii = g_malloc(length * 2 + 1); | 79 ascii = g_malloc(len * 2 + 1); |
80 | 80 |
81 for (i = 0; i < length; i++) | 81 for (i = 0; i < len; i++) |
82 snprintf(&ascii[i * 2], 3, "%02hhx", data[i]); | 82 snprintf(&ascii[i * 2], 3, "%02hhx", data[i]); |
83 | 83 |
84 return ascii; | 84 return ascii; |
85 } | 85 } |
86 | 86 |
87 int | 87 guint8 * |
88 gaim_base16_decode(const char *ascii, unsigned char **raw) | 88 gaim_base16_decode(const char *str, gsize *ret_len) |
89 { | 89 { |
90 int len, i, accumulator = 0; | 90 int len, i, accumulator = 0; |
91 unsigned char *data; | 91 guint8 *data; |
92 | 92 |
93 g_return_val_if_fail(ascii != NULL, 0); | 93 g_return_val_if_fail(str != NULL, NULL); |
94 | 94 |
95 len = strlen(ascii); | 95 len = strlen(str); |
96 | 96 |
97 g_return_val_if_fail(strlen(ascii) > 0, 0); | 97 g_return_val_if_fail(strlen(str) > 0, 0); |
98 g_return_val_if_fail(len % 2 > 0, 0); | 98 g_return_val_if_fail(len % 2 > 0, 0); |
99 | 99 |
100 data = g_malloc(len / 2); | 100 data = g_malloc(len / 2); |
101 | 101 |
102 for (i = 0; i < len; i++) | 102 for (i = 0; i < len; i++) |
104 if ((i % 2) == 0) | 104 if ((i % 2) == 0) |
105 accumulator = 0; | 105 accumulator = 0; |
106 else | 106 else |
107 accumulator <<= 4; | 107 accumulator <<= 4; |
108 | 108 |
109 if (isdigit(ascii[i])) | 109 if (isdigit(str[i])) |
110 accumulator |= ascii[i] - 48; | 110 accumulator |= str[i] - 48; |
111 else | 111 else |
112 { | 112 { |
113 switch(ascii[i]) | 113 switch(str[i]) |
114 { | 114 { |
115 case 'a': case 'A': accumulator |= 10; break; | 115 case 'a': case 'A': accumulator |= 10; break; |
116 case 'b': case 'B': accumulator |= 11; break; | 116 case 'b': case 'B': accumulator |= 11; break; |
117 case 'c': case 'C': accumulator |= 12; break; | 117 case 'c': case 'C': accumulator |= 12; break; |
118 case 'd': case 'D': accumulator |= 13; break; | 118 case 'd': case 'D': accumulator |= 13; break; |
123 | 123 |
124 if (i % 2) | 124 if (i % 2) |
125 data[(i - 1) / 2] = accumulator; | 125 data[(i - 1) / 2] = accumulator; |
126 } | 126 } |
127 | 127 |
128 *raw = data; | 128 if (ret_len != NULL) |
129 | 129 *ret_len = len / 2; |
130 return (len / 2); | 130 |
131 return data; | |
131 } | 132 } |
132 | 133 |
133 /************************************************************************** | 134 /************************************************************************** |
134 * Base64 Functions | 135 * Base64 Functions |
135 **************************************************************************/ | 136 **************************************************************************/ |
138 "0123456789+/"; | 139 "0123456789+/"; |
139 | 140 |
140 static const char xdigits[] = | 141 static const char xdigits[] = |
141 "0123456789abcdef"; | 142 "0123456789abcdef"; |
142 | 143 |
143 unsigned char * | 144 gchar * |
144 gaim_base64_encode(const unsigned char *in, size_t inlen) | 145 gaim_base64_encode(const guint8 *data, gsize len) |
145 { | 146 { |
146 char *out, *rv; | 147 char *out, *rv; |
147 | 148 |
148 g_return_val_if_fail(in != NULL, NULL); | 149 g_return_val_if_fail(data != NULL, NULL); |
149 g_return_val_if_fail(inlen > 0, NULL); | 150 g_return_val_if_fail(len > 0, NULL); |
150 | 151 |
151 rv = out = g_malloc(((inlen/3)+1)*4 + 1); | 152 rv = out = g_malloc(((len/3)+1)*4 + 1); |
152 | 153 |
153 for (; inlen >= 3; inlen -= 3) | 154 for (; len >= 3; len -= 3) |
154 { | 155 { |
155 *out++ = alphabet[in[0] >> 2]; | 156 *out++ = alphabet[data[0] >> 2]; |
156 *out++ = alphabet[((in[0] << 4) & 0x30) | (in[1] >> 4)]; | 157 *out++ = alphabet[((data[0] << 4) & 0x30) | (data[1] >> 4)]; |
157 *out++ = alphabet[((in[1] << 2) & 0x3c) | (in[2] >> 6)]; | 158 *out++ = alphabet[((data[1] << 2) & 0x3c) | (data[2] >> 6)]; |
158 *out++ = alphabet[in[2] & 0x3f]; | 159 *out++ = alphabet[data[2] & 0x3f]; |
159 in += 3; | 160 data += 3; |
160 } | 161 } |
161 | 162 |
162 if (inlen > 0) | 163 if (len > 0) |
163 { | 164 { |
164 unsigned char fragment; | 165 unsigned char fragment; |
165 | 166 |
166 *out++ = alphabet[in[0] >> 2]; | 167 *out++ = alphabet[data[0] >> 2]; |
167 fragment = (in[0] << 4) & 0x30; | 168 fragment = (data[0] << 4) & 0x30; |
168 | 169 |
169 if (inlen > 1) | 170 if (len > 1) |
170 fragment |= in[1] >> 4; | 171 fragment |= data[1] >> 4; |
171 | 172 |
172 *out++ = alphabet[fragment]; | 173 *out++ = alphabet[fragment]; |
173 *out++ = (inlen < 2) ? '=' : alphabet[(in[1] << 2) & 0x3c]; | 174 *out++ = (len < 2) ? '=' : alphabet[(data[1] << 2) & 0x3c]; |
174 *out++ = '='; | 175 *out++ = '='; |
175 } | 176 } |
176 | 177 |
177 *out = '\0'; | 178 *out = '\0'; |
178 | 179 |
179 return rv; | 180 return rv; |
180 } | 181 } |
181 | 182 |
182 void | 183 guint8 * |
183 gaim_base64_decode(const char *text, char **data, int *size) | 184 gaim_base64_decode(const char *str, gsize *ret_len) |
184 { | 185 { |
185 char *out = NULL; | 186 guint8 *out = NULL; |
186 char tmp = 0; | 187 char tmp = 0; |
187 const char *c; | 188 const char *c; |
188 gint32 tmp2 = 0; | 189 gint32 tmp2 = 0; |
189 int len = 0, n = 0; | 190 int len = 0, n = 0; |
190 | 191 |
191 g_return_if_fail(text != NULL); | 192 g_return_val_if_fail(str != NULL, NULL); |
192 g_return_if_fail(data != NULL); | 193 |
193 | 194 c = str; |
194 c = text; | |
195 | 195 |
196 while (*c) { | 196 while (*c) { |
197 if (*c >= 'A' && *c <= 'Z') { | 197 if (*c >= 'A' && *c <= 'Z') { |
198 tmp = *c - 'A'; | 198 tmp = *c - 'A'; |
199 } else if (*c >= 'a' && *c <= 'z') { | 199 } else if (*c >= 'a' && *c <= 'z') { |
208 c++; | 208 c++; |
209 continue; | 209 continue; |
210 } else if (*c == '=') { | 210 } else if (*c == '=') { |
211 if (n == 3) { | 211 if (n == 3) { |
212 out = g_realloc(out, len + 2); | 212 out = g_realloc(out, len + 2); |
213 out[len] = (char)(tmp2 >> 10) & 0xff; | 213 out[len] = (guint8)(tmp2 >> 10) & 0xff; |
214 len++; | 214 len++; |
215 out[len] = (char)(tmp2 >> 2) & 0xff; | 215 out[len] = (guint8)(tmp2 >> 2) & 0xff; |
216 len++; | 216 len++; |
217 } else if (n == 2) { | 217 } else if (n == 2) { |
218 out = g_realloc(out, len + 1); | 218 out = g_realloc(out, len + 1); |
219 out[len] = (char)(tmp2 >> 4) & 0xff; | 219 out[len] = (guint8)(tmp2 >> 4) & 0xff; |
220 len++; | 220 len++; |
221 } | 221 } |
222 break; | 222 break; |
223 } | 223 } |
224 tmp2 = ((tmp2 << 6) | (tmp & 0xff)); | 224 tmp2 = ((tmp2 << 6) | (tmp & 0xff)); |
225 n++; | 225 n++; |
226 if (n == 4) { | 226 if (n == 4) { |
227 out = g_realloc(out, len + 3); | 227 out = g_realloc(out, len + 3); |
228 out[len] = (char)((tmp2 >> 16) & 0xff); | 228 out[len] = (guint8)((tmp2 >> 16) & 0xff); |
229 len++; | 229 len++; |
230 out[len] = (char)((tmp2 >> 8) & 0xff); | 230 out[len] = (guint8)((tmp2 >> 8) & 0xff); |
231 len++; | 231 len++; |
232 out[len] = (char)(tmp2 & 0xff); | 232 out[len] = (guint8)(tmp2 & 0xff); |
233 len++; | 233 len++; |
234 tmp2 = 0; | 234 tmp2 = 0; |
235 n = 0; | 235 n = 0; |
236 } | 236 } |
237 c++; | 237 c++; |
238 } | 238 } |
239 | 239 |
240 out = g_realloc(out, len + 1); | 240 out = g_realloc(out, len + 1); |
241 out[len] = 0; | 241 out[len] = 0; |
242 | 242 |
243 *data = out; | 243 if (ret_len != NULL) |
244 | 244 *ret_len = len; |
245 if (size) | 245 |
246 *size = len; | 246 return out; |
247 } | 247 } |
248 | 248 |
249 /************************************************************************** | 249 /************************************************************************** |
250 * Quoted Printable Functions (see RFC 1341) | 250 * Quoted Printable Functions (see RFC 1341) |
251 **************************************************************************/ | 251 **************************************************************************/ |
408 case state_question4: | 408 case state_question4: |
409 if (*cur == '=') { /* Got the whole encoded-word */ | 409 if (*cur == '=') { /* Got the whole encoded-word */ |
410 char *charset = g_strndup(charset0, encoding0 - charset0 - 1); | 410 char *charset = g_strndup(charset0, encoding0 - charset0 - 1); |
411 char *encoding = g_strndup(encoding0, encoded_text0 - encoding0 - 1); | 411 char *encoding = g_strndup(encoding0, encoded_text0 - encoding0 - 1); |
412 char *encoded_text = g_strndup(encoded_text0, cur - encoded_text0 - 1); | 412 char *encoded_text = g_strndup(encoded_text0, cur - encoded_text0 - 1); |
413 char *decoded = NULL; | 413 guint8 *decoded = NULL; |
414 int dec_len; | 414 gsize dec_len; |
415 if (g_ascii_strcasecmp(encoding, "Q") == 0) | 415 if (g_ascii_strcasecmp(encoding, "Q") == 0) |
416 gaim_quotedp_decode(encoded_text, &decoded, &dec_len); | 416 gaim_quotedp_decode(encoded_text, &decoded, &dec_len); |
417 else if (g_ascii_strcasecmp(encoding, "B") == 0) | 417 else if (g_ascii_strcasecmp(encoding, "B") == 0) |
418 gaim_base64_decode(encoded_text, &decoded, &dec_len); | 418 decoded = gaim_base64_decode(encoded_text, &dec_len); |
419 else | 419 else |
420 decoded = NULL; | 420 decoded = NULL; |
421 if (decoded) { | 421 if (decoded) { |
422 gsize len; | 422 gsize len; |
423 char *converted = g_convert(decoded, dec_len, "utf-8", charset, NULL, &len, NULL); | 423 char *converted = g_convert(decoded, dec_len, "utf-8", charset, NULL, &len, NULL); |