comparison libpurple/log.c @ 15532:92107f572ac6

Fix SF Bug #1644796 In old_logger_read, we call g_markup_escape_text() on data from the filesystem without verifying that it's valid UTF-8. Bj«Órn Voigt says this can cause crashes. I have no idea if that's true or not, but either way, we should always be validating data on the way in. I've refactored some code to eliminate duplication and make things clearer. I'm also avoiding an unnecessary g_strdup() of the entire conversation in txt_logger_read() in some cases.
author Richard Laager <rlaager@wiktel.com>
date Sun, 04 Feb 2007 06:46:31 +0000
parents 443915ab77a1
children 47e9514f1c89
comparison
equal deleted inserted replaced
15531:40683a234203 15532:92107f572ac6
1041 * we'll assume the file is deletable. */ 1041 * we'll assume the file is deletable. */
1042 return TRUE; 1042 return TRUE;
1043 #endif 1043 #endif
1044 1044
1045 return FALSE; 1045 return FALSE;
1046 }
1047
1048 static char *process_txt_log(char *txt, char *to_free)
1049 {
1050 char *tmp;
1051
1052 /* The to_free argument allows us to save a
1053 * g_strdup() in some cases. */
1054
1055 if (to_free == NULL)
1056 to_free = txt;
1057
1058 /* g_markup_escape_text requires valid UTF-8 */
1059 if (!g_utf8_validate(txt, -1, NULL))
1060 {
1061 tmp = gaim_utf8_salvage(txt);
1062 g_free(to_free);
1063 to_free = txt = tmp;
1064 }
1065
1066 tmp = g_markup_escape_text(txt, -1);
1067 g_free(to_free);
1068 txt = gaim_markup_linkify(tmp);
1069 g_free(tmp);
1070
1071 return txt;
1046 } 1072 }
1047 1073
1048 #if 0 /* Maybe some other time. */ 1074 #if 0 /* Maybe some other time. */
1049 /**************** 1075 /****************
1050 ** XML LOGGER ** 1076 ** XML LOGGER **
1414 *flags = 0; 1440 *flags = 0;
1415 if (!data || !data->path) 1441 if (!data || !data->path)
1416 return g_strdup(_("<font color=\"red\"><b>Unable to find log path!</b></font>")); 1442 return g_strdup(_("<font color=\"red\"><b>Unable to find log path!</b></font>"));
1417 if (g_file_get_contents(data->path, &read, NULL, NULL)) { 1443 if (g_file_get_contents(data->path, &read, NULL, NULL)) {
1418 minus_header = strchr(read, '\n'); 1444 minus_header = strchr(read, '\n');
1419 if (!minus_header) 1445
1420 minus_header = g_strdup(read); 1446 if (minus_header)
1447 return process_txt_log(minus_header + 1, read);
1421 else 1448 else
1422 minus_header = g_strdup(minus_header + 1); 1449 return process_txt_log(read, NULL);
1423 g_free(read);
1424 minus_header2 = g_markup_escape_text(minus_header, -1);
1425 g_free(minus_header);
1426 read = gaim_markup_linkify(minus_header2);
1427 g_free(minus_header2);
1428 return read;
1429 } 1450 }
1430 return g_strdup_printf(_("<font color=\"red\"><b>Could not read file: %s</b></font>"), data->path); 1451 return g_strdup_printf(_("<font color=\"red\"><b>Could not read file: %s</b></font>"), data->path);
1431 } 1452 }
1432 1453
1433 static int txt_logger_total_size(GaimLogType type, const char *name, GaimAccount *account) 1454 static int txt_logger_total_size(GaimLogType type, const char *name, GaimAccount *account)
1728 fseek(file, data->offset, SEEK_SET); 1749 fseek(file, data->offset, SEEK_SET);
1729 fread(read, data->length, 1, file); 1750 fread(read, data->length, 1, file);
1730 fclose(file); 1751 fclose(file);
1731 read[data->length] = '\0'; 1752 read[data->length] = '\0';
1732 *flags = 0; 1753 *flags = 0;
1733 if(strstr(read, "<BR>")) 1754 if (strstr(read, "<BR>"))
1755 {
1734 *flags |= GAIM_LOG_READ_NO_NEWLINE; 1756 *flags |= GAIM_LOG_READ_NO_NEWLINE;
1735 else { 1757 return read;
1736 tmp = g_markup_escape_text(read, -1); 1758 }
1737 g_free(read); 1759
1738 read = gaim_markup_linkify(tmp); 1760 return process_txt_log(read, NULL);
1739 g_free(tmp);
1740 }
1741 return read;
1742 } 1761 }
1743 1762
1744 static int old_logger_size (GaimLog *log) 1763 static int old_logger_size (GaimLog *log)
1745 { 1764 {
1746 struct old_logger_data *data = log->logger_data; 1765 struct old_logger_data *data = log->logger_data;