[gmime-devel] parsing broken message_part inside a multipart



Hey,

When there's a message part inside a multipart, but the message part
is only headers followed by newline and then the boundary of the
multipart,
the gmime parser thinks the boundary and the next part in the
multipart is actually the mime part of the message part's message.

e.g:

Subject: foobar
Content-type: multipart/mixed; boundary=Boundary_mixed

--Boundary_mixed
Content-type: text/plain;

foo
--Boundary_mixed
Content-type: message/rfc822

--Boundary_mixed
Content-type: text/plain

bar
--Boundary_mixed--

Here the last part 'bar' will be added as the message of the
message/part instead as part of the multipart/mixed, and
g_mime_multipart_get_count() would return 2 instead of 3.

A little fix that worked for me (patch attached) was to check for
found_immediate_boundary() in the parser_scan_message_part() and to
construct an empty message  with a NULL mime part if the next line is
really the boundary. it seems to resolve the issue, but maybe I'm
missing something,

Thanks.
From 8c34d453243de70e50ec4cca705270d550824ece Mon Sep 17 00:00:00 2001
From: quatrix <evil legacy gmail com>
Date: Mon, 6 Feb 2012 02:21:34 +0200
Subject: [PATCH] fixed message_part inside multipart parsing error

---
 gmime/gmime-parser.c |   64 ++++++++++++++++++++++++++-----------------------
 1 files changed, 34 insertions(+), 30 deletions(-)

diff --git a/gmime/gmime-parser.c b/gmime/gmime-parser.c
index 321366c..b2181ef 100644
--- a/gmime/gmime-parser.c
+++ b/gmime/gmime-parser.c
@@ -96,6 +96,8 @@ static GMimeObject *parser_construct_leaf_part (GMimeParser *parser, ContentType
 static GMimeObject *parser_construct_multipart (GMimeParser *parser, ContentType *content_type,
 						int *found);
 
+static gboolean found_immediate_boundary (struct _GMimeParserPrivate *priv,  gboolean end);
+
 static GObjectClass *parent_class = NULL;
 
 /* size of read buffer */
@@ -1506,44 +1508,46 @@ static void
 parser_scan_message_part (GMimeParser *parser, GMimeMessagePart *mpart, int *found)
 {
 	struct _GMimeParserPrivate *priv = parser->priv;
+	GMimeMessage *message 			 = g_mime_message_new(FALSE);
+	GMimeObject *object   			 = NULL;
 	ContentType *content_type;
-	GMimeMessage *message;
-	GMimeObject *object;
 	GMimeStream *stream;
 	HeaderRaw *header;
 	
 	g_assert (priv->state == GMIME_PARSER_STATE_CONTENT);
-	
-	/* get the headers */
-	priv->state = GMIME_PARSER_STATE_HEADERS;
-	if (parser_step (parser) == GMIME_PARSER_STATE_ERROR) {
-		/* Note: currently cannot happen because
-		 * parser_step_headers() never returns error */
-		*found = FOUND_EOS;
-		return;
-	}
-	
-	message = g_mime_message_new (FALSE);
-	header = priv->headers;
-	while (header) {
-		g_mime_object_append_header ((GMimeObject *) message, header->name, header->value);
-		header = header->next;
+
+	if (!found_immediate_boundary(priv,  FALSE) && !found_immediate_boundary(priv,  TRUE)) {
+		/* get the headers */
+		priv->state = GMIME_PARSER_STATE_HEADERS;
+		if (parser_step (parser) == GMIME_PARSER_STATE_ERROR) {
+			/* Note: currently cannot happen because
+			 * parser_step_headers() never returns error */
+			*found = FOUND_EOS;
+			goto unref_message;
+		}
+		
+		header = priv->headers;
+		while (header) {
+			g_mime_object_append_header ((GMimeObject *) message, header->name, header->value);
+			header = header->next;
+		}
+		
+		content_type = parser_content_type (parser);
+		if (content_type_is_type (content_type, "multipart", "*"))
+			object = parser_construct_multipart (parser, content_type, found);
+		else
+			object = parser_construct_leaf_part (parser, content_type, found);
+		
+		content_type_destroy (content_type);
+
+		/* set the same raw header stream on the message's header-list */
+		if ((stream = g_mime_header_list_get_stream (object->headers)))
+			g_mime_header_list_set_stream (((GMimeObject *) message)->headers, stream);
 	}
-	
-	content_type = parser_content_type (parser);
-	if (content_type_is_type (content_type, "multipart", "*"))
-		object = parser_construct_multipart (parser, content_type, found);
-	else
-		object = parser_construct_leaf_part (parser, content_type, found);
-	
-	content_type_destroy (content_type);
 	message->mime_part = object;
-	
-	/* set the same raw header stream on the message's header-list */
-	if ((stream = g_mime_header_list_get_stream (object->headers)))
-		g_mime_header_list_set_stream (((GMimeObject *) message)->headers, stream);
-	
 	g_mime_message_part_set_message (mpart, message);
+
+unref_message:
 	g_object_unref (message);
 }
 
-- 
1.7.0.2



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]