[evolution-data-server] Bug #573125 - Crashes right after startup when having broken db summary



commit ceb906002ae20ffa8eb4d79407d8111b0aa0798d
Author: Milan Crha <mcrha redhat com>
Date:   Thu Dec 9 13:56:19 2010 +0100

    Bug #573125 - Crashes right after startup when having broken db summary

 camel/camel-db.c                                   |   44 ++++++----
 camel/camel-folder-summary.c                       |   96 ++++++++++++++------
 camel/camel-folder-summary.h                       |    4 +
 .../providers/groupwise/camel-groupwise-summary.c  |   16 +---
 camel/providers/imap/camel-imap-summary.c          |   21 ++---
 camel/providers/imapx/camel-imapx-summary.c        |   27 ++----
 camel/providers/local/camel-mbox-summary.c         |   12 +--
 camel/providers/nntp/camel-nntp-summary.c          |   17 +---
 8 files changed, 125 insertions(+), 112 deletions(-)
---
diff --git a/camel/camel-db.c b/camel/camel-db.c
index 84b6239..59b8a52 100644
--- a/camel/camel-db.c
+++ b/camel/camel-db.c
@@ -1089,10 +1089,14 @@ read_uids_callback (gpointer ref, gint ncol, gchar ** cols, gchar ** name)
 	#if 0
 	gint i;
 	for (i = 0; i < ncol; ++i) {
+		if (!name[i] || !cols[i])
+			continue;
+
 		if (!strcmp (name [i], "uid"))
 			g_ptr_array_add (array, (gchar *) (camel_pstring_strdup (cols[i])));
 	}
 	#else
+		if (cols[0])
 			g_ptr_array_add (array, (gchar *) (camel_pstring_strdup (cols[0])));
 	#endif
 
@@ -1186,6 +1190,9 @@ read_preview_callback (gpointer ref, gint ncol, gchar ** cols, gchar ** name)
 	gint i;
 
 	for (i = 0; i < ncol; ++i) {
+		if (!name[i] || !cols[i])
+			continue;
+
 		if (!strcmp (name [i], "uid"))
 			uid = camel_pstring_strdup (cols[i]);
 		else if (!strcmp (name [i], "preview"))
@@ -1250,20 +1257,24 @@ camel_db_write_preview_record (CamelDB *db,
 static gint
 read_vuids_callback (gpointer ref, gint ncol, gchar ** cols, gchar ** name)
 {
-	 GPtrArray *array = (GPtrArray *)ref;
+	GPtrArray *array = (GPtrArray *)ref;
 
-	 #if 0
-	 gint i;
+	#if 0
+	gint i;
 
-	 for (i = 0; i < ncol; ++i) {
-		  if (!strcmp (name [i], "vuid"))
-			   g_ptr_array_add (array, (gchar *) (camel_pstring_strdup (cols[i]+8)));
-	 }
-	 #else
-			   g_ptr_array_add (array, (gchar *) (camel_pstring_strdup (cols[0]+8)));
-	 #endif
+	for (i = 0; i < ncol; ++i) {
+		if (!name[i] || !cols[i] || strlen (cols[i]) <= 8)
+			continue;
 
-	 return 0;
+		if (!strcmp (name [i], "vuid"))
+			g_ptr_array_add (array, (gchar *) (camel_pstring_strdup (cols[i]+8)));
+	}
+	#else
+		if (cols[0] && strlen (cols[0]) > 8)
+			g_ptr_array_add (array, (gchar *) (camel_pstring_strdup (cols[0]+8)));
+	#endif
+
+	return 0;
 }
 
 /**
@@ -1740,14 +1751,11 @@ read_fir_callback (gpointer  ref, gint ncol, gchar ** cols, gchar ** name)
 	gint i;
 
 	d(g_print ("\nread_fir_callback called \n"));
-#if 0
-	record->folder_name = cols[0];
-	record->version = cols[1];
-	/* Just a sequential mapping of struct members to columns is enough I guess.
-	Needs some checking */
-#else
 
 	for (i = 0; i < ncol; ++i) {
+		if (!name[i] || !cols[i])
+			continue;
+
 		if (!strcmp (name [i], "folder_name"))
 			record->folder_name = g_strdup (cols[i]);
 
@@ -1782,7 +1790,7 @@ read_fir_callback (gpointer  ref, gint ncol, gchar ** cols, gchar ** name)
 			record->bdata = g_strdup (cols[i]);
 
 	}
-#endif
+
 	return 0;
 }
 
diff --git a/camel/camel-folder-summary.c b/camel/camel-folder-summary.c
index 03e47cb..1d7fa15 100644
--- a/camel/camel-folder-summary.c
+++ b/camel/camel-folder-summary.c
@@ -107,11 +107,6 @@ static GStaticMutex info_lock = G_STATIC_MUTEX_INIT;
 
 #define META_SUMMARY_SUFFIX_LEN 5 /* strlen("-meta") */
 
-#define EXTRACT_FIRST_STRING(val) len=strtoul (part, &part, 10); if (*part) part++; val=g_strndup (part, len); part+=len;
-#define EXTRACT_STRING(val) if (*part) part++; len=strtoul (part, &part, 10); if (*part) part++; val=g_strndup (part, len); part+=len;
-#define EXTRACT_FIRST_DIGIT(val) val=strtoul (part, &part, 10);
-#define EXTRACT_DIGIT(val) if (*part && *part == ' ') part++; val=strtoul (part, &part, 10);
-
 /* trivial lists, just because ... */
 struct _node {
 	struct _node *next;
@@ -355,16 +350,16 @@ message_info_from_db (CamelFolderSummary *s, CamelMIRecord *record)
 	mi->content = NULL;
 	part = record->part;
 	if (part) {
-		EXTRACT_FIRST_DIGIT (mi->message_id.id.part.hi)
-		EXTRACT_DIGIT (mi->message_id.id.part.lo)
-		EXTRACT_DIGIT (count)
+		mi->message_id.id.part.hi = bdata_extract_digit (&part);
+		mi->message_id.id.part.lo = bdata_extract_digit (&part);
+		count = bdata_extract_digit (&part);
 
 		if (count > 0) {
 			mi->references = g_malloc (sizeof (*mi->references) + ((count-1) * sizeof (mi->references->references[0])));
 			mi->references->size = count;
 			for (i=0;i<count;i++) {
-				EXTRACT_DIGIT (mi->references->references[i].id.part.hi)
-				EXTRACT_DIGIT (mi->references->references[i].id.part.lo)
+				mi->references->references[i].id.part.hi = bdata_extract_digit (&part);
+				mi->references->references[i].id.part.lo = bdata_extract_digit (&part);
 			}
 		} else
 			mi->references = NULL;
@@ -388,13 +383,14 @@ message_info_from_db (CamelFolderSummary *s, CamelMIRecord *record)
 
 	/* Extract User tags */
 	part = record->usertags;
-	EXTRACT_FIRST_DIGIT (count)
+	count = bdata_extract_digit (&part);
 	for (i=0;i<count;i++) {
-		gint len;
 		gchar *name, *value;
-		EXTRACT_STRING (name)
-		EXTRACT_STRING (value)
+
+		name = bdata_extract_string (&part);
+		value = bdata_extract_string (&part);
 		camel_tag_set (&mi->user_tags, name, value);
+
 		g_free (name);
 		g_free (value);
 	}
@@ -488,7 +484,6 @@ content_info_from_db (CamelFolderSummary *s, CamelMIRecord *record)
 	guint32 count, i;
 	CamelContentType *ct;
 	gchar *part = record->cinfo;
-	gint len;
 
 	io(printf("Loading content info from db\n"));
 
@@ -498,17 +493,17 @@ content_info_from_db (CamelFolderSummary *s, CamelMIRecord *record)
 	ci = camel_folder_summary_content_info_new (s);
 	if (*part == ' ') part++; /* Move off the space in the record*/
 
-	EXTRACT_FIRST_STRING (type)
-	EXTRACT_STRING (subtype)
+	type = bdata_extract_string (&part);
+	subtype = bdata_extract_string (&part);
 	ct = camel_content_type_new (type, subtype);
 	g_free (type);		/* can this be removed? */
 	g_free (subtype);
-	EXTRACT_DIGIT (count)
+	count = bdata_extract_digit (&part);
 
 	for (i = 0; i < count; i++) {
 		gchar *name, *value;
-		EXTRACT_STRING (name)
-		EXTRACT_STRING (value)
+		name = bdata_extract_string (&part);
+		value = bdata_extract_string (&part);
 
 		camel_content_type_set_param (ct, name, value);
 		/* TODO: do this so we dont have to double alloc/free */
@@ -518,10 +513,10 @@ content_info_from_db (CamelFolderSummary *s, CamelMIRecord *record)
 	ci->type = ct;
 
 	/* FIXME[disk-summary] move all these to camel pstring */
-	EXTRACT_STRING (ci->id);
-	EXTRACT_STRING (ci->description)
-	EXTRACT_STRING (ci->encoding)
-	EXTRACT_DIGIT (ci->size)
+	ci->id = bdata_extract_string (&part);
+	ci->description = bdata_extract_string (&part);
+	ci->encoding = bdata_extract_string (&part);
+	ci->size = bdata_extract_digit (&part);
 
 	record->cinfo = part; /* Keep moving the cursor in the record */
 
@@ -1397,7 +1392,7 @@ perform_content_info_load_from_db (CamelFolderSummary *s, CamelMIRecord *mir)
 	if (!part)
 		return ci;
 	if (*part == ' ') part++;
-	EXTRACT_DIGIT (count);
+	count = bdata_extract_digit (&part);
 
 	mir->cinfo = part;
 	for (i=0;i<count;i++) {
@@ -1841,6 +1836,8 @@ mir_from_cols (CamelMIRecord *mir, CamelFolderSummary *s, gint ncol, gchar ** co
 	gint i;
 
 	for (i = 0; i < ncol; ++i) {
+		if (!name[i] || !cols[i])
+			continue;
 
 		if (!strcmp (name [i], "uid"))
 			mir->uid = (gchar *) camel_pstring_strdup (cols[i]);
@@ -1910,8 +1907,8 @@ camel_read_mir_callback (gpointer  ref, gint ncol, gchar ** cols, gchar ** name)
 	mir_from_cols (mir, s, ncol, cols, name);
 
 	camel_folder_summary_lock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
-	if (g_hash_table_lookup (s->loaded_infos, mir->uid)) {
-		/* Unlock and better return*/
+	if (!mir->uid || g_hash_table_lookup (s->loaded_infos, mir->uid)) {
+		/* Unlock and better return */
 		camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 		camel_db_camel_mir_free (mir);
 		return ret;
@@ -4902,3 +4899,48 @@ camel_folder_summary_unlock (CamelFolderSummary *summary,
 			g_return_if_reached ();
 	}
 }
+
+gint
+bdata_extract_digit (/* const */ gchar **part)
+{
+	if (!part || !*part || !**part)
+		return 0;
+
+	if (**part == ' ')
+		*part += 1;
+
+	if (!**part)
+		return 0;
+
+	return strtoul (*part, part, 10);
+}
+
+/* expecting "digit-value", where digit is length of the value */
+gchar *
+bdata_extract_string (/* const */ gchar **part)
+{
+	gint len, has_len;
+	gchar *val;
+
+	len = bdata_extract_digit (part);
+
+	/* might be a '-' sign */
+	if (part && *part && **part)
+		*part += 1;
+
+	if (len <= 0 || !part || !*part || !**part)
+		return g_strdup ("");
+
+	if (!**part)
+		return g_strdup ("");
+
+	has_len = strlen (*part);
+	if (has_len < len)
+		len = has_len;
+
+	val = g_strndup (*part, len);
+	*part += len;
+
+	return val;
+}
+	
\ No newline at end of file
diff --git a/camel/camel-folder-summary.h b/camel/camel-folder-summary.h
index d536a99..3958346 100644
--- a/camel/camel-folder-summary.h
+++ b/camel/camel-folder-summary.h
@@ -521,6 +521,10 @@ gint camel_folder_summary_migrate_infos (CamelFolderSummary *s);
 void camel_folder_summary_lock   (CamelFolderSummary *summary, CamelFolderSummaryLock lock);
 void camel_folder_summary_unlock (CamelFolderSummary *summary, CamelFolderSummaryLock lock);
 
+/* utility functions for bdata string decomposition */
+gint   bdata_extract_digit (/* const */ gchar **part);
+gchar *bdata_extract_string (/* const */ gchar **part);
+
 G_END_DECLS
 
 #endif /* CAMEL_FOLDER_SUMMARY_H */
diff --git a/camel/providers/groupwise/camel-groupwise-summary.c b/camel/providers/groupwise/camel-groupwise-summary.c
index b155ddb..ccedf9e 100644
--- a/camel/providers/groupwise/camel-groupwise-summary.c
+++ b/camel/providers/groupwise/camel-groupwise-summary.c
@@ -38,9 +38,6 @@
 
 #define CAMEL_GW_SUMMARY_VERSION (1)
 
-#define EXTRACT_FIRST_DIGIT(val) part ? val=strtoul (part, &part, 10) : 0;
-#define EXTRACT_DIGIT(val) part++; part ? val=strtoul (part, &part, 10) : 0;
-
 #define d(x)
 
 /*Prototypes*/
@@ -144,13 +141,10 @@ summary_header_from_db (CamelFolderSummary *s, CamelFIRecord *mir)
 
 	part = mir->bdata;
 
-	if (part)
-		EXTRACT_FIRST_DIGIT (gms->version);
-
-	if (part)
-		EXTRACT_DIGIT (gms->validity);
+	gms->version = bdata_extract_digit (&part);
+	gms->validity = bdata_extract_digit (&part);
 
-	if (part && part++) {
+	if (part && *part && part++) {
 		gms->time_string = g_strdup (part);
 	}
 
@@ -213,7 +207,7 @@ message_info_from_db (CamelFolderSummary *s, CamelMIRecord *mir)
 	if (info) {
 		gchar *part = mir->bdata;
 		iinfo = (CamelGroupwiseMessageInfo *)info;
-		EXTRACT_FIRST_DIGIT (iinfo->server_flags)
+		iinfo->server_flags = bdata_extract_digit (&part);
 	}
 
 	return info;}
@@ -260,7 +254,7 @@ content_info_from_db (CamelFolderSummary *s, CamelMIRecord *mir)
 		if (*part == ' ')
 			part++;
 		if (part) {
-			EXTRACT_FIRST_DIGIT (type);
+			type = bdata_extract_digit (&part);
 		}
 	}
 	mir->cinfo = part;
diff --git a/camel/providers/imap/camel-imap-summary.c b/camel/providers/imap/camel-imap-summary.c
index f648740..1160002 100644
--- a/camel/providers/imap/camel-imap-summary.c
+++ b/camel/providers/imap/camel-imap-summary.c
@@ -36,9 +36,6 @@
 
 #define CAMEL_IMAP_SUMMARY_VERSION (3)
 
-#define EXTRACT_FIRST_DIGIT(val) val=strtoul (part, &part, 10);
-#define EXTRACT_DIGIT(val) if (*part) part++; val=strtoul (part, &part, 10);
-
 static gint summary_header_load (CamelFolderSummary *, FILE *);
 static gint summary_header_save (CamelFolderSummary *, FILE *);
 
@@ -192,13 +189,8 @@ summary_header_from_db (CamelFolderSummary *s, CamelFIRecord *mir)
 
 	part = mir->bdata;
 
-	if (part) {
-		EXTRACT_FIRST_DIGIT (ims->version)
-	}
-
-	if (part) {
-		EXTRACT_DIGIT (ims->validity)
-	}
+	ims->version = bdata_extract_digit (&part);
+	ims->validity = bdata_extract_digit (&part);
 
 	if (ims->version > CAMEL_IMAP_SUMMARY_VERSION) {
 		g_warning("Unkown summary version\n");
@@ -280,11 +272,10 @@ message_info_from_db (CamelFolderSummary *s, CamelMIRecord *mir)
 
 	info = CAMEL_FOLDER_SUMMARY_CLASS (camel_imap_summary_parent_class)->message_info_from_db (s, mir);
 	if (info) {
-		gchar *part = g_strdup (mir->bdata), *tmp;
-		tmp = part;
+		gchar *part = mir->bdata;
+
 		iinfo = (CamelImapMessageInfo *)info;
-		EXTRACT_FIRST_DIGIT (iinfo->server_flags)
-		g_free (tmp);
+		iinfo->server_flags = bdata_extract_digit (&part);
 	}
 
 	return info;
@@ -347,7 +338,7 @@ content_info_from_db (CamelFolderSummary *s, CamelMIRecord *mir)
 		if (*part == ' ')
 			part++;
 		if (part) {
-			EXTRACT_FIRST_DIGIT (type);
+			type = bdata_extract_digit (&part);
 		}
 	}
 	mir->cinfo = part;
diff --git a/camel/providers/imapx/camel-imapx-summary.c b/camel/providers/imapx/camel-imapx-summary.c
index 40cec91..a71d2b3 100644
--- a/camel/providers/imapx/camel-imapx-summary.c
+++ b/camel/providers/imapx/camel-imapx-summary.c
@@ -35,9 +35,6 @@
 
 #define CAMEL_IMAPX_SUMMARY_VERSION (4)
 
-#define EXTRACT_FIRST_DIGIT(val) val=strtoull (part, &part, 10);
-#define EXTRACT_DIGIT(val) if (*part) part++; val=strtoull (part, &part, 10);
-
 static gint summary_header_load (CamelFolderSummary *, FILE *);
 static gint summary_header_save (CamelFolderSummary *, FILE *);
 
@@ -202,19 +199,12 @@ summary_header_from_db (CamelFolderSummary *s, CamelFIRecord *mir)
 
 	part = mir->bdata;
 
-	if (part) {
-		EXTRACT_FIRST_DIGIT (ims->version)
-	}
-
-	if (part) {
-		EXTRACT_DIGIT (ims->validity)
-	}
+	ims->version = bdata_extract_digit (&part);
+	ims->validity = bdata_extract_digit (&part);
 
 	if (ims->version >= 4) {
-		if (part)
-			EXTRACT_DIGIT (ims->uidnext);
-		if (part)
-			EXTRACT_DIGIT (ims->modseq);
+		ims->uidnext = bdata_extract_digit (&part);
+		ims->modseq = bdata_extract_digit (&part);
 	}
 
 	if (ims->version > CAMEL_IMAPX_SUMMARY_VERSION) {
@@ -313,11 +303,10 @@ message_info_from_db (CamelFolderSummary *s, CamelMIRecord *mir)
 
 	info = folder_summary_class->message_info_from_db (s, mir);
 	if (info) {
-		gchar *part = g_strdup (mir->bdata), *tmp;
-		tmp = part;
+		gchar *part = mir->bdata;
+
 		iinfo = (CamelIMAPXMessageInfo *)info;
-		EXTRACT_FIRST_DIGIT (iinfo->server_flags)
-		g_free (tmp);
+		iinfo->server_flags = bdata_extract_digit (&part);
 	}
 
 	return info;
@@ -396,7 +385,7 @@ content_info_from_db (CamelFolderSummary *s, CamelMIRecord *mir)
 		if (*part == ' ')
 			part++;
 		if (part) {
-			EXTRACT_FIRST_DIGIT (type);
+			type = bdata_extract_digit (&part);
 		}
 	}
 	mir->cinfo = part;
diff --git a/camel/providers/local/camel-mbox-summary.c b/camel/providers/local/camel-mbox-summary.c
index 5ce1476..f0eb45d 100644
--- a/camel/providers/local/camel-mbox-summary.c
+++ b/camel/providers/local/camel-mbox-summary.c
@@ -43,9 +43,6 @@
 
 #define CAMEL_MBOX_SUMMARY_VERSION (1)
 
-#define EXTRACT_DIGIT(val) part++; val=strtoul (part, &part, 10);
-#define EXTRACT_FIRST_DIGIT(val) val=strtoul (part, &part, 10);
-
 static CamelFIRecord * summary_header_to_db (CamelFolderSummary *, GError **error);
 static gint summary_header_from_db (CamelFolderSummary *, CamelFIRecord *);
 static CamelMessageInfo * message_info_from_db (CamelFolderSummary *s, CamelMIRecord *record);
@@ -233,8 +230,8 @@ summary_header_from_db (CamelFolderSummary *s, struct _CamelFIRecord *fir)
 
 	part = fir->bdata;
 	if (part) {
-		EXTRACT_DIGIT (mbs->version)
-		EXTRACT_DIGIT (mbs->folder_size)
+		mbs->version = bdata_extract_digit (&part);
+		mbs->folder_size = bdata_extract_digit (&part);
 	}
 
 	return 0;
@@ -393,15 +390,14 @@ static CamelMessageInfo *
 message_info_from_db (CamelFolderSummary *s, struct _CamelMIRecord *mir)
 {
 	CamelMessageInfo *mi;
-	gchar *part;
 
 	mi = CAMEL_FOLDER_SUMMARY_CLASS (camel_mbox_summary_parent_class)->message_info_from_db (s, mir);
 
 	if (mi) {
 		CamelMboxMessageInfo *mbi = (CamelMboxMessageInfo *)mi;
-		part = mir->bdata;
+		gchar *part = mir->bdata;
 		if (part) {
-			EXTRACT_FIRST_DIGIT (mbi->frompos)
+			mbi->frompos = bdata_extract_digit (&part);
 		}
 	}
 
diff --git a/camel/providers/nntp/camel-nntp-summary.c b/camel/providers/nntp/camel-nntp-summary.c
index 68129a7..82cf030 100644
--- a/camel/providers/nntp/camel-nntp-summary.c
+++ b/camel/providers/nntp/camel-nntp-summary.c
@@ -44,9 +44,6 @@
 
 #define CAMEL_NNTP_SUMMARY_VERSION (1)
 
-#define EXTRACT_FIRST_DIGIT(val) val=strtoul (part, &part, 10);
-#define EXTRACT_DIGIT(val) part++; val=strtoul (part, &part, 10);
-
 #define CAMEL_NNTP_SUMMARY_GET_PRIVATE(obj) \
 	(G_TYPE_INSTANCE_GET_PRIVATE \
 	((obj), CAMEL_TYPE_NNTP_SUMMARY, CamelNNTPSummaryPrivate))
@@ -143,17 +140,9 @@ summary_header_from_db (CamelFolderSummary *s, CamelFIRecord *mir)
 
 	part = mir->bdata;
 
-	if (part) {
-		EXTRACT_FIRST_DIGIT (cns->version)
-	}
-
-	if (part) {
-		EXTRACT_DIGIT (cns->high)
-	}
-
-	if (part) {
-		EXTRACT_DIGIT (cns->low)
-	}
+	cns->version = bdata_extract_digit (&part);
+	cns->high = bdata_extract_digit (&part);
+	cns->low = bdata_extract_digit (&part);
 
 	return 0;
 }



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]