[PATCH] notmuch_message_file_get_header: use talloc for hash table entries
authordavid <david@tethera.net>
Tue, 11 Dec 2012 13:54:47 +0000 (09:54 +2000)
committerW. Trevor King <wking@tremily.us>
Fri, 7 Nov 2014 17:52:03 +0000 (09:52 -0800)
04/06193955f07f0749a45ba1cac65f62be8eb891 [new file with mode: 0644]

diff --git a/04/06193955f07f0749a45ba1cac65f62be8eb891 b/04/06193955f07f0749a45ba1cac65f62be8eb891
new file mode 100644 (file)
index 0000000..4809341
--- /dev/null
@@ -0,0 +1,186 @@
+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