Apply patch from upstream:
fix: crash handling keywords/labels
When an email is read by NeoMutt the labels are stored in linked list of
strings. These strings are used as keys in a hash table of all labels.
If NeoMutt reads another email with the same label, it's given a
reference to the same hash.
Now imagine that the first email is deleted -- the list of labels is
also deleted, so that hash now has invalid keys.
This commit maintains a linked list of all labels and uses that for the
hash table keys. It's not very efficient, but it avoids having to
change the hash table code.
Note: dgc (the keywords author) has created a new version which will
supplant this one, soon.
f8160285f2
Bump PKGREVISION.
This commit is contained in:
parent
4a18fa65d0
commit
0668933e51
5 changed files with 189 additions and 2 deletions
|
@ -1,6 +1,7 @@
|
|||
# $NetBSD: Makefile,v 1.12 2016/10/04 21:53:08 wiz Exp $
|
||||
# $NetBSD: Makefile,v 1.13 2016/10/06 16:27:15 wiz Exp $
|
||||
|
||||
DISTNAME= neomutt-20161003
|
||||
PKGREVISION= 1
|
||||
CATEGORIES= mail
|
||||
MASTER_SITES= ${MASTER_SITE_GITHUB:=neomutt/}
|
||||
GITHUB_TAG= ${DISTNAME}
|
||||
|
@ -19,6 +20,7 @@ CONFIGURE_ARGS+= --enable-external-dotlock
|
|||
CONFIGURE_ARGS+= --enable-imap
|
||||
CONFIGURE_ARGS+= --enable-notmuch
|
||||
CONFIGURE_ARGS+= --enable-pop
|
||||
CONFIGURE_ARGS+= CFLAGS="-g -O0"
|
||||
|
||||
EGDIR= ${PREFIX}/share/examples/mutt
|
||||
CONF_FILES= ${EGDIR}/Muttrc ${PKG_SYSCONFDIR}/Muttrc
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
$NetBSD: distinfo,v 1.9 2016/10/04 11:05:06 wiz Exp $
|
||||
$NetBSD: distinfo,v 1.10 2016/10/06 16:27:15 wiz Exp $
|
||||
|
||||
SHA1 (neomutt-20161003.tar.gz) = d0849c7efaa7e099b17137d8f5f90b9a201142f1
|
||||
RMD160 (neomutt-20161003.tar.gz) = c69fe3dba35c3341987b6eb21b4bc0a1eb546762
|
||||
SHA512 (neomutt-20161003.tar.gz) = f3b42e0bf12038bfdce20db30d2ac4ee60a4ce317894ff035a4180a53d0899936aef6f809c52ef8786eab6b247e98ae244578d00a5dafb44e04f4b3ccc84b592
|
||||
Size (neomutt-20161003.tar.gz) = 2656280 bytes
|
||||
SHA1 (patch-hash.c) = 63df8e500d91f0dffb24801b84dc7155539d34a5
|
||||
SHA1 (patch-hash.h) = ddc94cfaeead9800f5f902de9f4255803122463d
|
||||
SHA1 (patch-headers.c) = 8d985b9dfc717c5c30e9fb314c33b35d61dcaf56
|
||||
|
|
28
mail/neomutt/patches/patch-hash.c
Normal file
28
mail/neomutt/patches/patch-hash.c
Normal file
|
@ -0,0 +1,28 @@
|
|||
$NetBSD: patch-hash.c,v 1.1 2016/10/06 16:27:15 wiz Exp $
|
||||
|
||||
Fix: crash handling keywords/labels
|
||||
https://github.com/neomutt/neomutt/commit/f8160285f285c0bc3c93a2672ea1169af2f04481
|
||||
|
||||
--- hash.c.orig 2016-10-03 11:27:32.000000000 +0000
|
||||
+++ hash.c
|
||||
@@ -153,6 +153,20 @@ void *hash_find_hash (const HASH * table
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+void hash_set_data (HASH *table, const char *key, void *data)
|
||||
+{
|
||||
+ if (!table)
|
||||
+ return;
|
||||
+
|
||||
+ unsigned int hash = table->hash_string ((unsigned char *) key, table->nelem);
|
||||
+
|
||||
+ struct hash_elem *ptr = table->table[hash];
|
||||
+ if (!ptr)
|
||||
+ return;
|
||||
+
|
||||
+ ptr->data = data;
|
||||
+}
|
||||
+
|
||||
void hash_delete_hash (HASH * table, int hash, const char *key, const void *data,
|
||||
void (*destroy) (void *))
|
||||
{
|
15
mail/neomutt/patches/patch-hash.h
Normal file
15
mail/neomutt/patches/patch-hash.h
Normal file
|
@ -0,0 +1,15 @@
|
|||
$NetBSD: patch-hash.h,v 1.1 2016/10/06 16:27:15 wiz Exp $
|
||||
|
||||
Fix: crash handling keywords/labels
|
||||
https://github.com/neomutt/neomutt/commit/f8160285f285c0bc3c93a2672ea1169af2f04481
|
||||
|
||||
--- hash.h.orig 2016-10-03 11:27:32.000000000 +0000
|
||||
+++ hash.h
|
||||
@@ -46,6 +46,7 @@ void *hash_find_hash (const HASH * table
|
||||
void hash_delete_hash (HASH * table, int hash, const char *key, const void *data,
|
||||
void (*destroy) (void *));
|
||||
void hash_destroy (HASH ** hash, void (*destroy) (void *));
|
||||
+void hash_set_data (HASH *table, const char *key, void *data);
|
||||
|
||||
struct hash_walk_state {
|
||||
int index;
|
139
mail/neomutt/patches/patch-headers.c
Normal file
139
mail/neomutt/patches/patch-headers.c
Normal file
|
@ -0,0 +1,139 @@
|
|||
$NetBSD: patch-headers.c,v 1.1 2016/10/06 16:27:15 wiz Exp $
|
||||
|
||||
Fix: crash handling keywords/labels
|
||||
https://github.com/neomutt/neomutt/commit/f8160285f285c0bc3c93a2672ea1169af2f04481
|
||||
|
||||
--- headers.c.orig 2016-10-03 11:27:32.000000000 +0000
|
||||
+++ headers.c
|
||||
@@ -28,6 +28,11 @@
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
+/* The labels are used as keys in the Labels hash.
|
||||
+ * The keys must have a longer lifespan than the hash.
|
||||
+ */
|
||||
+static LIST *LabelList = NULL;
|
||||
+
|
||||
void mutt_edit_headers (const char *editor,
|
||||
const char *body,
|
||||
HEADER *msg,
|
||||
@@ -215,6 +220,65 @@ void mutt_edit_headers (const char *edit
|
||||
}
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * label_add - Add to a list of all labels
|
||||
+ * @label: Label name to keep
|
||||
+ *
|
||||
+ * Add an item to our LIST of all labels.
|
||||
+ *
|
||||
+ * The keys in the Label HASH must have a longer lifespan than the HASH itself.
|
||||
+ * We keep them in an (inefficient) linked list.
|
||||
+ *
|
||||
+ * Note: We don't check for duplicates.
|
||||
+ *
|
||||
+ * Returns:
|
||||
+ * NULL on error
|
||||
+ * LIST* new LIST item, on success
|
||||
+ */
|
||||
+static LIST *label_add (const char *label)
|
||||
+{
|
||||
+ if (!label)
|
||||
+ return NULL;
|
||||
+
|
||||
+ LIST *n = mutt_new_list();
|
||||
+
|
||||
+ /* Insert our new LIST item at the front */
|
||||
+ n->data = safe_strdup (label);
|
||||
+ n->next = LabelList;
|
||||
+ LabelList = n;
|
||||
+
|
||||
+ return n;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * label_delete - Delete from a list of all labels
|
||||
+ * @label: Label name to remove
|
||||
+ *
|
||||
+ * Delete an item from our LIST of all labels.
|
||||
+ *
|
||||
+ * The keys in the Label HASH must have a longer lifespan than the HASH itself.
|
||||
+ * We keep them in an (inefficient) linked list.
|
||||
+ */
|
||||
+static void label_delete (const char *label)
|
||||
+{
|
||||
+ if (!label || !LabelList)
|
||||
+ return;
|
||||
+
|
||||
+ LIST *l;
|
||||
+ LIST **prev;
|
||||
+
|
||||
+ for (l = LabelList, prev = &LabelList; l; prev = &l->next, l = l->next)
|
||||
+ {
|
||||
+ if (mutt_strcmp (label, l->data) == 0)
|
||||
+ {
|
||||
+ *prev = l->next;
|
||||
+ FREE(&l->data);
|
||||
+ FREE(&l);
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
void mutt_label_ref_dec(ENVELOPE *env)
|
||||
{
|
||||
uintptr_t count;
|
||||
@@ -227,14 +291,21 @@ void mutt_label_ref_dec(ENVELOPE *env)
|
||||
{
|
||||
if (label->data == NULL)
|
||||
continue;
|
||||
+
|
||||
count = (uintptr_t)hash_find(Labels, label->data);
|
||||
- if (count)
|
||||
+ count--;
|
||||
+ if (count > 0)
|
||||
{
|
||||
+ /* Existing label, decrease refcount */
|
||||
+ hash_set_data (Labels, label->data, (void*) count);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ /* Old label */
|
||||
hash_delete(Labels, label->data, NULL, NULL);
|
||||
- count--;
|
||||
- if (count > 0)
|
||||
- hash_insert(Labels, label->data, (void *)count, 0);
|
||||
+ label_delete (label->data);
|
||||
}
|
||||
+
|
||||
dprint(1, (debugfile, "--label %s: %d\n", label->data, count));
|
||||
}
|
||||
}
|
||||
@@ -251,11 +322,22 @@ void mutt_label_ref_inc(ENVELOPE *env)
|
||||
{
|
||||
if (label->data == NULL)
|
||||
continue;
|
||||
- count = (uintptr_t)hash_find(Labels, label->data);
|
||||
- if (count)
|
||||
- hash_delete(Labels, label->data, NULL, NULL);
|
||||
- count++; /* was zero if not found */
|
||||
- hash_insert(Labels, label->data, (void *)count, 0);
|
||||
+
|
||||
+ count = (uintptr_t) hash_find(Labels, label->data);
|
||||
+ count++;
|
||||
+ if (count > 1)
|
||||
+ {
|
||||
+ /* Existing label, increase refcount */
|
||||
+ hash_set_data (Labels, label->data, (void*) count);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ /* New label */
|
||||
+ const char *dup_label = safe_strdup (label->data);
|
||||
+ label_add (dup_label);
|
||||
+ hash_insert(Labels, dup_label, (void *) count, 0);
|
||||
+ }
|
||||
+
|
||||
dprint(1, (debugfile, "++label %s: %d\n", label->data, count));
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue