<<< Date Index >>>     <<< Thread Index >>>

Re: hcache broken (slightly)



Hello,
pop3 hcache segfaults, because it uses the hcache infrastructure in a
way it isn't supposed to be. The problem is that the pop code uses

Fetching message headers... [1/593]mutt: hcache.c:606: mutt_hcache_dump: 
Assertion `header->data == ((void *)0)' failed.
                                                                                
                                        Aborted

header->data, header->tree, header->thread pointers to thread members driver
specific data, which are not stored and so contain pointers up on restores to
memory locations from the previous run. There are two ways around:

        - Find a way to avoid dumping the uncached structures
        - Follow my lead in hcache.c and implement dumping / restore functions
        - Understand the logic behind the header->thread pointers and
          recalculate them on restore

Please apply the attached patch to catch such problems in the future
early: It adds assertions that test that HEADER data which will not be
dumped/restored are always zero and doesn't contain any data to malloced
areas.

Greetings,
        Thomas
diff --git a/hcache.c b/hcache.c
index 0974600..d2157b7 100644
--- a/hcache.c
+++ b/hcache.c
@@ -24,6 +24,8 @@ #if HAVE_CONFIG_H
 #include "config.h"
 #endif                         /* HAVE_CONFIG_H */
 
+#include <assert.h>
+
 #if HAVE_QDBM
 #include <depot.h>
 #include <cabin.h>
@@ -358,6 +360,12 @@ dump_body(BODY * c, unsigned char *d, in
   d = dump_char(c->filename, d, off);
   d = dump_char(c->d_filename, d, off);
 
+  assert(c->content == NULL);
+  assert(c->next == NULL);
+  assert(c->parts == NULL);
+  assert(c->hdr == NULL);
+  assert(c->aptr == NULL);
+
   return d;
 }
 
@@ -592,6 +600,19 @@ mutt_hcache_dump(header_cache_t *h, HEAD
 
   d = dump_envelope(header->env, d, off);
   d = dump_body(header->content, d, off);
+
+  assert(header->path == NULL);
+  assert(header->tree == NULL);
+  assert(header->thread == NULL);
+
+#ifdef MIXMASTER
+  assert(header->chain == NULL);
+#endif
+
+#if defined USE_POP || defined USE_IMAP
+  assert(header->data == NULL);
+#endif
+
   d = dump_char(header->maildir_flags, d, off);
 
   return d;
diff --git a/pop.c b/pop.c