Mercurial > pidgin.yaz
comparison src/util.c @ 7840:13334c29799b
[gaim-migrate @ 8493]
Ok, so the MSN MIME email header thing hasn't been going so well.
This is my function again. It almost works some of the time, but
at least it doesn't crash.
See, this is why no one likes mimes.
committer: Tailor Script <tailor@pidgin.im>
author | Mark Doliner <mark@kingant.net> |
---|---|
date | Fri, 12 Dec 2003 23:42:02 +0000 |
parents | 1663c076a744 |
children | 1ce040412bd5 |
comparison
equal
deleted
inserted
replaced
7839:10fe9f6d2b23 | 7840:13334c29799b |
---|---|
277 } | 277 } |
278 | 278 |
279 /************************************************************************** | 279 /************************************************************************** |
280 * MIME Functions | 280 * MIME Functions |
281 **************************************************************************/ | 281 **************************************************************************/ |
282 #define OUT_CHARSET "utf-8" | |
283 | |
284 static char * | 282 static char * |
285 gaim_mime_decode_word(const char *charset, const char *encoding, const char *str) | 283 gaim_mime_decode_word(const char *charset, const char *encoding, const char *str) |
286 { | 284 { |
287 char *decoded, *converted; | 285 char *decoded, *converted; |
288 int len = 0; | 286 int len = 0; |
295 else if (g_ascii_strcasecmp(encoding, "B") == 0) | 293 else if (g_ascii_strcasecmp(encoding, "B") == 0) |
296 gaim_base64_decode(str, &decoded, &len); | 294 gaim_base64_decode(str, &decoded, &len); |
297 else | 295 else |
298 return NULL; | 296 return NULL; |
299 | 297 |
300 converted = g_convert(decoded, len, OUT_CHARSET, charset, NULL, NULL, NULL); | 298 converted = g_convert(decoded, len, "utf-8", charset, NULL, NULL, NULL); |
301 g_free(decoded); | 299 g_free(decoded); |
302 | 300 |
303 return converted; | 301 return converted; |
304 } | 302 } |
305 | 303 |
316 orig = g_strdup(str); | 314 orig = g_strdup(str); |
317 donedeal = g_string_sized_new(strlen(orig)); | 315 donedeal = g_string_sized_new(strlen(orig)); |
318 | 316 |
319 /* One iteration per encoded-word */ | 317 /* One iteration per encoded-word */ |
320 end_of_last = orig; | 318 end_of_last = orig; |
321 while ((start = strstr(end_of_last, "=?")) && (end = strstr(start, "?="))) { | 319 while ((start = strstr(end_of_last, "=?"))) { |
320 /* | |
321 * Get to the end of the encoded word by finding the first ?, | |
322 * the second ?, then finally the ?= | |
323 */ | |
324 if (((end = strstr(start + 2, "?")) == NULL) || | |
325 ((end = strstr(end + 1, "?")) == NULL) || | |
326 ((end = strstr(end + 2, "?=")) == NULL)) { | |
327 break; | |
328 } | |
329 | |
322 /* Append everything from the end of the last encoded-word to the beginning of the next */ | 330 /* Append everything from the end of the last encoded-word to the beginning of the next */ |
323 tmp = g_strndup(end_of_last, (start - end_of_last)); | 331 tmp = g_strndup(end_of_last, (start - end_of_last)); |
324 donedeal = g_string_append(donedeal, tmp); | 332 donedeal = g_string_append(donedeal, tmp); |
325 g_free(tmp); | 333 g_free(tmp); |
326 | 334 |
327 /* Split the encoded word */ | 335 /* Split the encoded word */ |
328 tmp = g_strndup(start + 2, end - start - 4); | 336 tmp = g_strndup(start + 2, end - start - 2); |
329 encoded_word = g_strsplit(tmp, "?", 3); | 337 encoded_word = g_strsplit(tmp, "?", 3); |
330 g_free(tmp); | 338 g_free(tmp); |
331 charset = encoded_word[0]; | 339 charset = encoded_word[0]; |
332 encoding = charset != NULL ? encoded_word[1] : NULL; | 340 encoding = charset != NULL ? encoded_word[1] : NULL; |
333 word = encoding != NULL ? encoded_word[2] : NULL; | 341 word = encoding != NULL ? encoded_word[2] : NULL; |
334 g_strfreev(encoded_word); | |
335 | 342 |
336 /* Convert the decoded word to utf8 and append it */ | 343 /* Convert the decoded word to utf8 and append it */ |
337 tmp = gaim_mime_decode_word(charset, encoding, word); | 344 tmp = gaim_mime_decode_word(charset, encoding, word); |
338 donedeal = g_string_append(donedeal, tmp); | 345 if (tmp != NULL) { |
339 g_free(tmp); | 346 donedeal = g_string_append(donedeal, tmp); |
340 | 347 g_free(tmp); |
341 g_free(charset); | 348 } |
342 g_free(encoding); | 349 |
343 g_free(word); | 350 g_strfreev(encoded_word); |
351 | |
352 end_of_last = end + 2; | |
344 } | 353 } |
345 | 354 |
346 /* Append everything from the end of the last encoded-word to the end of the string */ | 355 /* Append everything from the end of the last encoded-word to the end of the string */ |
347 tmp = g_strndup(end_of_last, ((orig + strlen(orig)) - end_of_last)); | 356 tmp = g_strndup(end_of_last, ((orig + strlen(orig)) - end_of_last)); |
348 donedeal = g_string_append(donedeal, tmp); | 357 donedeal = g_string_append(donedeal, tmp); |
352 tmp = donedeal->str; | 361 tmp = donedeal->str; |
353 g_string_free(donedeal, FALSE); | 362 g_string_free(donedeal, FALSE); |
354 g_free(orig); | 363 g_free(orig); |
355 | 364 |
356 return tmp; | 365 return tmp; |
357 | 366 } |
358 #if 0 | 367 |
359 /* The shx version! */ | 368 |
360 const char *cur, *mark; | |
361 const char *unencoded, *encoded; | |
362 char *n, *new; | |
363 | |
364 n = new = g_malloc(strlen(str)); | |
365 | |
366 gaim_debug(GAIM_DEBUG_ERROR, "XXX", "new is %d\n", new); | |
367 | |
368 /* | |
369 * Here we will be looking for encoded words and if they seem to be | |
370 * valid then decode them. | |
371 * They are of this form: =?charset?encoding?text?= | |
372 */ | |
373 for ( unencoded = cur = str; | |
374 (encoded = cur = strstr(cur, "=?")); | |
375 unencoded = cur) { | |
376 | |
377 gboolean found_word = FALSE; | |
378 int i, num, len, dec_len; | |
379 char *decoded, *converted; | |
380 char *tokens[3]; | |
381 | |
382 /* Let's look for tokens, they are between ?'s */ | |
383 for (cur += 2, mark = cur, num = 0; *cur; cur++) { | |
384 if (*cur == '?') { | |
385 if (num > 2) | |
386 /* No more than 3 tokens. */ | |
387 break; | |
388 | |
389 tokens[num++] = g_strndup(mark, cur - mark); | |
390 | |
391 mark = (cur + 1); | |
392 | |
393 if (mark[0] == '=' && mark[1] == '\0') { | |
394 found_word = TRUE; | |
395 break; | |
396 } | |
397 } | |
398 #if 0 | |
399 /* I think this is rarely going to happen, if at all */ | |
400 else if ((num < 2) && (strchr("()<>@,;:/[]", *cur))) | |
401 /* There can't be these characters in the first two tokens. */ | |
402 break; | |
403 else if ((num == 2) && (*cur == ' ')) | |
404 /* There can't be spaces in the third token. */ | |
405 break; | |
406 #endif | |
407 } | |
408 | |
409 cur += 2; | |
410 gaim_debug(GAIM_DEBUG_ERROR, "XXX", "new is %d, this is probably different than above, that's bad\n", new); | |
411 if (found_word) { | |
412 /* We found an encoded word. */ | |
413 /* =?charset?encoding?text?= */ | |
414 len = encoded - unencoded; | |
415 n = strncpy(n, unencoded, len) + len; | |
416 | |
417 if (g_ascii_strcasecmp(tokens[1], "Q") == 0) | |
418 gaim_quotedp_decode(tokens[2], &decoded, &dec_len); | |
419 else if (g_ascii_strcasecmp(tokens[1], "B") == 0) | |
420 gaim_base64_decode(tokens[2], &decoded, &dec_len); | |
421 else | |
422 decoded = NULL; | |
423 | |
424 if (decoded) { | |
425 converted = g_convert(decoded, dec_len, OUT_CHARSET, tokens[0], | |
426 NULL, &len, NULL); | |
427 g_free(decoded); | |
428 | |
429 n = strncpy(n, converted, len) + len; | |
430 g_free(converted); | |
431 } | |
432 } else { | |
433 /* Some unencoded text. */ | |
434 len = cur - unencoded; | |
435 n = strncpy(n, unencoded, len) + len; | |
436 } | |
437 | |
438 for (i = 0; i < num; i++) | |
439 g_free(tokens[i]); | |
440 } | |
441 | |
442 *n = '\0'; | |
443 | |
444 /* There is unencoded text at the end. */ | |
445 if (*unencoded) | |
446 n = strcpy(n, unencoded); | |
447 | |
448 return new; | |
449 #endif | |
450 } | |
451 | 369 |
452 /************************************************************************** | 370 /************************************************************************** |
453 * Date/Time Functions | 371 * Date/Time Functions |
454 **************************************************************************/ | 372 **************************************************************************/ |
455 const char * | 373 const char * |