message.c: Free leaked memory in notmuch_message object
[notmuch] / message.c
index 03583c8d0e43f122215bdbcdd6e7c9ca92242a79..e6488a3711cfdb9d976421878c2d1cc1911638c0 100644 (file)
--- a/message.c
+++ b/message.c
@@ -37,6 +37,8 @@ struct _notmuch_message {
     /* Header storage */
     int restrict_headers;
     GHashTable *headers;
+    int broken_headers;
+    int good_headers;
 
     /* Parsing state */
     char *line;
@@ -102,6 +104,12 @@ notmuch_message_close (notmuch_message_t *message)
     if (message == NULL)
        return;
 
+    if (message->line)
+       free (message->line);
+
+    if (message->value.size)
+       free (message->value.str);
+
     if (message->headers)
        g_hash_table_unref (message->headers);
 
@@ -234,12 +242,21 @@ notmuch_message_get_header (notmuch_message_t *message,
        colon = strchr (message->line, ':');
 
        if (colon == NULL) {
-           fprintf (stderr, "Warning: Unexpected non-header line: %s\n",
-                    message->line);
+           message->broken_headers++;
+           /* A simple heuristic for giving up on things that just
+            * don't look like mail messages. */
+           if (message->broken_headers >= 10 &&
+               message->good_headers < 5)
+           {
+               message->parsing_finished = 1;
+               continue;
+           }
            NEXT_HEADER_LINE (NULL);
            continue;
        }
 
+       message->good_headers++;
+
        header = xstrndup (message->line, colon - message->line);
 
        if (message->restrict_headers &&
@@ -262,8 +279,9 @@ notmuch_message_get_header (notmuch_message_t *message,
 
        match = (strcasecmp (header, header_desired) == 0);
 
-       g_hash_table_insert (message->headers, header,
-                            xstrdup (message->value.str));
+       value = xstrdup (message->value.str);
+
+       g_hash_table_insert (message->headers, header, value);
 
        if (match)
            return value;