--- /dev/null
+Return-Path: <bremner@tethera.net>\r
+X-Original-To: notmuch@notmuchmail.org\r
+Delivered-To: notmuch@notmuchmail.org\r
+Received: from localhost (localhost [127.0.0.1])\r
+ by olra.theworths.org (Postfix) with ESMTP id 34FDE431FB6\r
+ for <notmuch@notmuchmail.org>; Tue, 11 Dec 2012 05:55:00 -0800 (PST)\r
+X-Virus-Scanned: Debian amavisd-new at olra.theworths.org\r
+X-Spam-Flag: NO\r
+X-Spam-Score: 0\r
+X-Spam-Level: \r
+X-Spam-Status: No, score=0 tagged_above=-999 required=5 tests=[none]\r
+ autolearn=disabled\r
+Received: from olra.theworths.org ([127.0.0.1])\r
+ by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024)\r
+ with ESMTP id 1CUXW4uQPhTb for <notmuch@notmuchmail.org>;\r
+ Tue, 11 Dec 2012 05:54:59 -0800 (PST)\r
+Received: from tesseract.cs.unb.ca (tesseract.cs.unb.ca [131.202.240.238])\r
+ (using TLSv1 with cipher AES256-SHA (256/256 bits))\r
+ (No client certificate requested)\r
+ by olra.theworths.org (Postfix) with ESMTPS id 9196B431FAF\r
+ for <notmuch@notmuchmail.org>; Tue, 11 Dec 2012 05:54:59 -0800 (PST)\r
+Received: from fctnnbsc30w-142167090129.dhcp-dynamic.fibreop.nb.bellaliant.net\r
+ ([142.167.90.129] helo=zancas.localnet)\r
+ by tesseract.cs.unb.ca with esmtpsa\r
+ (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16) (Exim 4.72)\r
+ (envelope-from <bremner@tethera.net>)\r
+ id 1TiQIU-00014a-4D; Tue, 11 Dec 2012 09:54:58 -0400\r
+Received: from bremner by zancas.localnet with local (Exim 4.80)\r
+ (envelope-from <bremner@tethera.net>)\r
+ id 1TiQIO-0001nc-Ha; Tue, 11 Dec 2012 09:54:52 -0400\r
+From: david@tethera.net\r
+To: notmuch@notmuchmail.org\r
+Subject: [PATCH] notmuch_message_file_get_header: use talloc for hash table\r
+ entries\r
+Date: Tue, 11 Dec 2012 09:54:47 -0400\r
+Message-Id: <1355234087-6886-1-git-send-email-david@tethera.net>\r
+X-Mailer: git-send-email 1.7.10.4\r
+In-Reply-To: <id:m2a9tlfaza.fsf@guru.guru-group.fi>\r
+References: <id:m2a9tlfaza.fsf@guru.guru-group.fi>\r
+X-Spam_bar: -\r
+Cc: David Bremner <bremner@debian.org>\r
+X-BeenThere: notmuch@notmuchmail.org\r
+X-Mailman-Version: 2.1.13\r
+Precedence: list\r
+List-Id: "Use and development of the notmuch mail system."\r
+ <notmuch.notmuchmail.org>\r
+List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,\r
+ <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>\r
+List-Archive: <http://notmuchmail.org/pipermail/notmuch>\r
+List-Post: <mailto:notmuch@notmuchmail.org>\r
+List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>\r
+List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,\r
+ <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
+X-List-Received-Date: Tue, 11 Dec 2012 13:55:00 -0000\r
+\r
+From: David Bremner <bremner@debian.org>\r
+\r
+Before this patch there is some strange mix of malloc/free and\r
+g_malloc/g_free. In particular, the pointer returned by\r
+g_mime_utils_header_decode_text is from the following line in\r
+rfc2047_decode_tokens\r
+\r
+ return g_string_free (decoded, FALSE);\r
+\r
+The docs for g_string_free say\r
+\r
+ Frees the memory allocated for the GString. If free_segment is TRUE\r
+ it also frees the character data. If it's FALSE, the caller gains\r
+ ownership of the buffer and must free it after use with g_free().\r
+\r
+On the other hand, as Tomi points out in id:m2a9tlfaza.fsf@guru.guru-group.fi,\r
+Sometimes the string is allocated with with xmalloc.\r
+\r
+This patch tries to unify everything to use talloc.\r
+\r
+Because of difficulties in error handling in a callback, we defer\r
+deallocation of hash entries to when the parent context (the message)\r
+is destroyed.\r
+\r
+The function talloc_str_from_g might be overkill; it is currently only\r
+used once.\r
+---\r
+ lib/message-file.c | 35 +++++++++++++++++++++++++----------\r
+ 1 file changed, 25 insertions(+), 10 deletions(-)\r
+\r
+diff --git a/lib/message-file.c b/lib/message-file.c\r
+index 915aba8..f84e929 100644\r
+--- a/lib/message-file.c\r
++++ b/lib/message-file.c\r
+@@ -73,6 +73,15 @@ strcase_hash (const void *ptr)\r
+ return hash;\r
+ }\r
+ \r
++static inline\r
++char *talloc_str_from_g (void *ctx, char *str)\r
++{\r
++ char *dup = talloc_strdup (ctx, str);\r
++ g_free(str);\r
++\r
++ return dup;\r
++}\r
++\r
+ static int\r
+ _notmuch_message_file_destructor (notmuch_message_file_t *message)\r
+ {\r
+@@ -108,10 +117,13 @@ _notmuch_message_file_open_ctx (void *ctx, const char *filename)\r
+ if (message->file == NULL)\r
+ goto FAIL;\r
+ \r
++ /* We choose not to pass talloc_free (or some wrapper), because we have no\r
++ * good way of dealing with its failure condition.\r
++ */\r
+ message->headers = g_hash_table_new_full (strcase_hash,\r
+ strcase_equal,\r
+- free,\r
+- free);\r
++ NULL,\r
++ NULL);\r
+ \r
+ message->parsing_started = 0;\r
+ message->parsing_finished = 0;\r
+@@ -151,7 +163,7 @@ notmuch_message_file_restrict_headersv (notmuch_message_file_t *message,\r
+ if (header == NULL)\r
+ break;\r
+ g_hash_table_insert (message->headers,\r
+- xstrdup (header), NULL);\r
++ talloc_strdup (message, header), NULL);\r
+ }\r
+ \r
+ message->restrict_headers = 1;\r
+@@ -299,13 +311,13 @@ notmuch_message_file_get_header (notmuch_message_file_t *message,\r
+ \r
+ message->good_headers++;\r
+ \r
+- header = xstrndup (message->line, colon - message->line);\r
++ header = talloc_strndup (message, message->line, colon - message->line);\r
+ \r
+ if (message->restrict_headers &&\r
+ ! g_hash_table_lookup_extended (message->headers,\r
+ header, NULL, NULL))\r
+ {\r
+- free (header);\r
++ talloc_free (header);\r
+ NEXT_HEADER_LINE (NULL);\r
+ continue;\r
+ }\r
+@@ -324,7 +336,10 @@ notmuch_message_file_get_header (notmuch_message_file_t *message,\r
+ else\r
+ match = (strcasecmp (header, header_desired) == 0);\r
+ \r
+- decoded_value = g_mime_utils_header_decode_text (message->value.str);\r
++ decoded_value =\r
++ talloc_str_from_g (message,\r
++ g_mime_utils_header_decode_text (message->value.str));\r
++\r
+ header_sofar = (char *)g_hash_table_lookup (message->headers, header);\r
+ /* we treat the Received: header special - we want to concat ALL of \r
+ * the Received: headers we encounter.\r
+@@ -337,11 +352,11 @@ notmuch_message_file_get_header (notmuch_message_file_t *message,\r
+ /* we need to add the header to those we already collected */\r
+ newhdr = strlen(decoded_value);\r
+ hdrsofar = strlen(header_sofar);\r
+- combined_header = xmalloc(hdrsofar + newhdr + 2);\r
++ combined_header = talloc_size (message, hdrsofar + newhdr + 2);\r
+ strncpy(combined_header,header_sofar,hdrsofar);\r
+ *(combined_header+hdrsofar) = ' ';\r
+ strncpy(combined_header+hdrsofar+1,decoded_value,newhdr+1);\r
+- free (decoded_value);\r
++ talloc_free (decoded_value);\r
+ g_hash_table_insert (message->headers, header, combined_header);\r
+ }\r
+ } else {\r
+@@ -349,8 +364,8 @@ notmuch_message_file_get_header (notmuch_message_file_t *message,\r
+ /* Only insert if we don't have a value for this header, yet. */\r
+ g_hash_table_insert (message->headers, header, decoded_value);\r
+ } else {\r
+- free (header);\r
+- free (decoded_value);\r
++ talloc_free (header);\r
++ talloc_free (decoded_value);\r
+ decoded_value = header_sofar;\r
+ }\r
+ }\r
+-- \r
+1.7.10.4\r
+\r