Bug #573125 - Crashes right after startup when having broken db summary
authorMilan Crha <mcrha@redhat.com>
Thu, 9 Dec 2010 12:56:19 +0000 (13:56 +0100)
committerMilan Crha <mcrha@redhat.com>
Thu, 9 Dec 2010 12:56:19 +0000 (13:56 +0100)
camel/camel-db.c
camel/camel-folder-summary.c
camel/camel-folder-summary.h
camel/providers/groupwise/camel-groupwise-summary.c
camel/providers/imap/camel-imap-summary.c
camel/providers/imapx/camel-imapx-summary.c
camel/providers/local/camel-mbox-summary.c
camel/providers/nntp/camel-nntp-summary.c

index 84b6239..59b8a52 100644 (file)
@@ -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;
 }
 
index 03e47cb..1d7fa15 100644 (file)
@@ -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
index d536a99..3958346 100644 (file)
@@ -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 */
index b155ddb..ccedf9e 100644 (file)
@@ -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;
index f648740..1160002 100644 (file)
@@ -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;
index 40cec91..a71d2b3 100644 (file)
@@ -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;
index 5ce1476..f0eb45d 100644 (file)
@@ -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);
                }
        }
 
index 68129a7..82cf030 100644 (file)
@@ -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;
 }