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 *