comparison src/util.c @ 7858:1ce040412bd5

[gaim-migrate @ 8512] Another try with revo/shx's mime function. committer: Tailor Script <tailor@pidgin.im>
author Mark Doliner <mark@kingant.net>
date Sun, 14 Dec 2003 07:00:43 +0000
parents 13334c29799b
children 7e1bb4deca24
comparison
equal deleted inserted replaced
7857:43f63ff8a6d8 7858:1ce040412bd5
302 } 302 }
303 303
304 char * 304 char *
305 gaim_mime_decode_field(const char *str) 305 gaim_mime_decode_field(const char *str)
306 { 306 {
307 /*
308 * This is revo/shx's version. It has had some problems with
309 * crashing, but it's probably a better implementation.
310 */
311 const char *cur, *mark;
312 const char *unencoded, *encoded;
313 char *n, *new;
314
315 n = new = g_malloc(strlen(str) + 1);
316
317 /* Here we will be looking for encoded words and if they seem to be
318 * valid then decode them.
319 * They are of this form: =?charset?encoding?text?=
320 */
321
322 for (unencoded = cur = str; (encoded = cur = strstr(cur, "=?")); unencoded = cur) {
323 gboolean found_word = FALSE;
324 int i, num, len, dec_len;
325 char *decoded, *converted;
326 char *tokens[3];
327
328 /* Let's look for tokens, they are between ?'s */
329 for (cur += 2, mark = cur, num = 0; *cur; cur++) {
330 if (*cur == '?') {
331 if (num > 2)
332 /* No more than 3 tokens. */
333 break;
334
335 tokens[num++] = g_strndup(mark, cur - mark);
336
337 mark = (cur + 1);
338
339 if (*mark == '=') {
340 found_word = TRUE;
341 break;
342 }
343 }
344 #if 0
345 /* I think this is rarely going to happend, if at all */
346 else if ((num < 2) && (strchr("()<>@,;:/[]", *cur)))
347 /* There can't be these characters in the first two tokens. */
348 break;
349 else if ((num == 2) && (*cur == ' '))
350 /* There can't be spaces in the third token. */
351 break;
352 #endif
353 }
354
355 cur += 2;
356
357 if (found_word) {
358 /* We found an encoded word. */
359 /* =?charset?encoding?text?= */
360
361 /* Some unencoded text. */
362 len = encoded - unencoded;
363 n = strncpy(n, unencoded, len) + len;
364
365 if (g_ascii_strcasecmp(tokens[1], "Q") == 0)
366 gaim_quotedp_decode(tokens[2], &decoded, &dec_len);
367 else if (g_ascii_strcasecmp(tokens[1], "B") == 0)
368 gaim_base64_decode(tokens[2], &decoded, &dec_len);
369 else
370 decoded = NULL;
371
372 if (decoded) {
373 converted = g_convert(decoded, dec_len, "utf-8", tokens[0], NULL, &len, NULL);
374
375 if (converted) {
376 n = strncpy(n, converted, len) + len;
377 g_free(converted);
378 } else if (len) {
379 converted = g_convert(decoded, len, "utf-8", tokens[0], NULL, &len, NULL);
380 n = strncpy(n, converted, len) + len;
381 g_free(converted);
382 }
383 g_free(decoded);
384 }
385 } else {
386 /* Some unencoded text. */
387 len = cur - unencoded;
388 n = strncpy(n, unencoded, len) + len;
389 }
390
391 for (i = 0; i < num; i++)
392 g_free(tokens[i]);
393 }
394
395 *n = '\0';
396
397 /* There is unencoded text at the end. */
398 if (*unencoded)
399 n = strcpy(n, unencoded);
400
401 return new;
402 #if 0
403 /*
404 * This is KingAnt's function. It should work, but I don't know if it
405 * follows the RFC fully.
406 */
307 GString *donedeal; 407 GString *donedeal;
308 char *orig, *start, *end, *end_of_last, *tmp; 408 char *orig, *start, *end, *end_of_last, *tmp;
309 char **encoded_word; 409 char **encoded_word;
310 char *charset, *encoding, *word; 410 char *charset, *encoding, *word;
311 411
317 /* One iteration per encoded-word */ 417 /* One iteration per encoded-word */
318 end_of_last = orig; 418 end_of_last = orig;
319 while ((start = strstr(end_of_last, "=?"))) { 419 while ((start = strstr(end_of_last, "=?"))) {
320 /* 420 /*
321 * Get to the end of the encoded word by finding the first ?, 421 * Get to the end of the encoded word by finding the first ?,
322 * the second ?, then finally the ?= 422 * the second ?, then finally the ?= If we can't find any of
423 * these, then break out of here because this isn't actually an
424 * encoded word.
323 */ 425 */
324 if (((end = strstr(start + 2, "?")) == NULL) || 426 if (((end = strstr(start + 2, "?")) == NULL) ||
325 ((end = strstr(end + 1, "?")) == NULL) || 427 ((end = strstr(end + 1, "?")) == NULL) ||
326 ((end = strstr(end + 2, "?=")) == NULL)) { 428 ((end = strstr(end + 2, "?=")) == NULL)) {
327 break; 429 break;
361 tmp = donedeal->str; 463 tmp = donedeal->str;
362 g_string_free(donedeal, FALSE); 464 g_string_free(donedeal, FALSE);
363 g_free(orig); 465 g_free(orig);
364 466
365 return tmp; 467 return tmp;
468 #endif
366 } 469 }
367 470
368 471
369 472
370 /************************************************************************** 473 /**************************************************************************