[gmime] Fixed to fail to parse non-mime streams as messages



commit 836b283960ccaa1e9c5787d5fc7ddf4e263394fc
Author: Jeffrey Stedfast <fejj gnome org>
Date:   Wed Jun 15 18:35:19 2011 -0400

    Fixed to fail to parse non-mime streams as messages
    
    2011-06-15  Jeffrey Stedfast  <fejj gnome org>
    
    	* gmime/gmime-parser.c: Added new state, MESSAGE_HEADERS, which
    	behaves the same as HEADERS but is only ever set when we are
    	parsing the toplevel GMimeMessage object.
    	(parser_step_headers): Be slightly more strict in handling
    	malformed headers in the MESSAGE_HEADERS state so that trying to
    	parse non-message streams fails (e.g. if someone tries to parse
    a
    	jpeg stream).

 ChangeLog            |   10 ++++++++++
 gmime/gmime-parser.c |   19 ++++++++++++++-----
 2 files changed, 24 insertions(+), 5 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index b0f391f..d62557d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,15 @@
 2011-06-15  Jeffrey Stedfast  <fejj gnome org>
 
+	* gmime/gmime-parser.c: Added new state, MESSAGE_HEADERS, which
+	behaves the same as HEADERS but is only ever set when we are
+	parsing the toplevel GMimeMessage object.
+	(parser_step_headers): Be slightly more strict in handling
+	malformed headers in the MESSAGE_HEADERS state so that trying to
+	parse non-message streams fails (e.g. if someone tries to parse a
+	jpeg stream).
+
+2011-06-15  Jeffrey Stedfast  <fejj gnome org>
+
 	* gmime/gmime-gpg-context.c: Define nfds_t on OSX.
 
 2011-06-10  Jeffrey Stedfast  <fejj gnome org>
diff --git a/gmime/gmime-parser.c b/gmime/gmime-parser.c
index 204aea4..321366c 100644
--- a/gmime/gmime-parser.c
+++ b/gmime/gmime-parser.c
@@ -113,6 +113,7 @@ enum {
 	GMIME_PARSER_STATE_ERROR = -1,
 	GMIME_PARSER_STATE_INIT,
 	GMIME_PARSER_STATE_FROM,
+	GMIME_PARSER_STATE_MESSAGE_HEADERS,
 	GMIME_PARSER_STATE_HEADERS,
 	GMIME_PARSER_STATE_HEADERS_END,
 	GMIME_PARSER_STATE_CONTENT,
@@ -824,7 +825,7 @@ parser_step_from (GMimeParser *parser)
 	
  got_from:
 	
-	priv->state = GMIME_PARSER_STATE_HEADERS;
+	priv->state = GMIME_PARSER_STATE_MESSAGE_HEADERS;
 	
 	priv->inptr = inptr;
 	
@@ -1051,7 +1052,7 @@ parser_step_headers (GMimeParser *parser)
 					
 					/* Note: see optimization comment [1] */
 					*inend = '\n';
-				} else if (*inptr == ':') {
+				} else {
 					valid = FALSE;
 				}
 				
@@ -1060,12 +1061,18 @@ parser_step_headers (GMimeParser *parser)
 					    && !strncmp (start, "From ", 5))
 						goto next_message;
 					
-					if (priv->headers != NULL || *inptr == ':') {
+					if (priv->headers != NULL) {
 						/* probably the start of the content,
 						 * a broken mailer didn't terminate the
 						 * headers with an empty line. *sigh* */
 						goto content_start;
 					}
+					
+					if (priv->state == GMIME_PARSER_STATE_MESSAGE_HEADERS) {
+						/* Be a little more strict when scanning toplevel message headers. */
+						priv->state = GMIME_PARSER_STATE_ERROR;
+						return -1;
+					}
 				}
 			}
 			
@@ -1251,13 +1258,14 @@ parser_step (GMimeParser *parser)
 		if (priv->scan_from)
 			priv->state = GMIME_PARSER_STATE_FROM;
 		else
-			priv->state = GMIME_PARSER_STATE_HEADERS;
+			priv->state = GMIME_PARSER_STATE_MESSAGE_HEADERS;
 		break;
 	case GMIME_PARSER_STATE_FROM:
 		priv->message_headers_begin = -1;
 		priv->message_headers_end = -1;
 		parser_step_from (parser);
 		break;
+	case GMIME_PARSER_STATE_MESSAGE_HEADERS:
 	case GMIME_PARSER_STATE_HEADERS:
 		parser_step_headers (parser);
 		
@@ -1780,6 +1788,7 @@ parser_construct_part (GMimeParser *parser)
 	int found;
 	
 	/* get the headers */
+	priv->state = GMIME_PARSER_STATE_HEADERS;
 	while (priv->state < GMIME_PARSER_STATE_HEADERS_END) {
 		if (parser_step (parser) == GMIME_PARSER_STATE_ERROR)
 			return NULL;
@@ -1828,7 +1837,7 @@ parser_construct_message (GMimeParser *parser)
 	int found;
 	
 	/* scan the from-line if we are parsing an mbox */
-	while (priv->state != GMIME_PARSER_STATE_HEADERS) {
+	while (priv->state != GMIME_PARSER_STATE_MESSAGE_HEADERS) {
 		if (parser_step (parser) == GMIME_PARSER_STATE_ERROR)
 			return NULL;
 	}



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