changeset 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 40683a234203
children 47e9514f1c89
files libpurple/log.c
diffstat 1 files changed, 35 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/libpurple/log.c	Sun Feb 04 05:55:54 2007 +0000
+++ b/libpurple/log.c	Sun Feb 04 06:46:31 2007 +0000
@@ -1045,6 +1045,32 @@
 	return FALSE;
 }
 
+static char *process_txt_log(char *txt, char *to_free)
+{
+	char *tmp;
+
+	/* The to_free argument allows us to save a
+	 * g_strdup() in some cases. */
+
+	if (to_free == NULL)
+		to_free = txt;
+
+	/* g_markup_escape_text requires valid UTF-8 */
+	if (!g_utf8_validate(txt, -1, NULL))
+	{
+		tmp = gaim_utf8_salvage(txt);
+		g_free(to_free);
+		to_free = txt = tmp;
+	}
+
+	tmp = g_markup_escape_text(txt, -1);
+	g_free(to_free);
+	txt = gaim_markup_linkify(tmp);
+	g_free(tmp);
+
+	return txt;
+}
+
 #if 0 /* Maybe some other time. */
 /****************
  ** XML LOGGER **
@@ -1416,16 +1442,11 @@
 		return g_strdup(_("<font color=\"red\"><b>Unable to find log path!</b></font>"));
 	if (g_file_get_contents(data->path, &read, NULL, NULL)) {
 		minus_header = strchr(read, '\n');
-		if (!minus_header)
-			minus_header = g_strdup(read);
+
+		if (minus_header)
+			return process_txt_log(minus_header + 1, read);
 		else
-			minus_header = g_strdup(minus_header + 1);
-		g_free(read);
-		minus_header2 = g_markup_escape_text(minus_header, -1);
-		g_free(minus_header);
-		read = gaim_markup_linkify(minus_header2);
-		g_free(minus_header2);
-		return read;
+			return process_txt_log(read, NULL);
 	}
 	return g_strdup_printf(_("<font color=\"red\"><b>Could not read file: %s</b></font>"), data->path);
 }
@@ -1730,15 +1751,13 @@
 	fclose(file);
 	read[data->length] = '\0';
 	*flags = 0;
-	if(strstr(read, "<BR>"))
+	if (strstr(read, "<BR>"))
+	{
 		*flags |= GAIM_LOG_READ_NO_NEWLINE;
-	else {
-		tmp = g_markup_escape_text(read, -1);
-		g_free(read);
-		read = gaim_markup_linkify(tmp);
-		g_free(tmp);
+		return read;
 	}
-	return read;
+
+	return process_txt_log(read, NULL);
 }
 
 static int old_logger_size (GaimLog *log)