Mercurial > pidgin
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 /************************************************************************** |