dovecot-2.2: lib-http: When receiving unexpected input in HTTP r...

dovecot at dovecot.org dovecot at dovecot.org
Mon Sep 28 12:01:33 UTC 2015


details:   http://hg.dovecot.org/dovecot-2.2/rev/cfee3a8b35ec
changeset: 19237:cfee3a8b35ec
user:      Timo Sirainen <tss at iki.fi>
date:      Mon Sep 28 14:34:05 2015 +0300
description:
lib-http: When receiving unexpected input in HTTP response, include a longer snippet of it in the error.

diffstat:

 src/lib-http/http-response-parser.c |  49 +++++++++++++++++++++++++++---------
 1 files changed, 37 insertions(+), 12 deletions(-)

diffs (95 lines):

diff -r c30c30c1e642 -r cfee3a8b35ec src/lib-http/http-response-parser.c
--- a/src/lib-http/http-response-parser.c	Mon Sep 28 13:54:28 2015 +0300
+++ b/src/lib-http/http-response-parser.c	Mon Sep 28 14:34:05 2015 +0300
@@ -1,6 +1,7 @@
 /* Copyright (c) 2013-2015 Dovecot authors, see the included COPYING file */
 
 #include "lib.h"
+#include "str.h"
 #include "istream.h"
 #include "http-parser.h"
 #include "http-date.h"
@@ -92,15 +93,37 @@
 	return 1;
 }
 
-static inline const char *_chr_sanitize(unsigned char c)
+static const char *_reply_sanitize(struct http_message_parser *parser)
 {
-	if (c >= 0x20 && c < 0x7F)
-		return t_strdup_printf("`%c'", c);
-	if (c == 0x0a)
-		return "<LF>";
-	if (c == 0x0d)
-		return "<CR>";
-	return t_strdup_printf("<0x%02x>", c);
+	string_t *str = t_str_new(32);
+	const unsigned char *p;
+	unsigned int i;
+	bool quote_open = FALSE;
+
+	i_assert(parser->cur < parser->end);
+	for (p = parser->cur, i = 0; p < parser->end && i < 20; p++, i++) {
+		if (*p >= 0x20 && *p < 0x7F) {
+			if (!quote_open) {
+				str_append_c(str, '`');
+				quote_open = TRUE;
+			}
+			str_append_c(str, *p);
+		} else {
+			if (quote_open) {
+				str_append_c(str, '\'');
+				quote_open = FALSE;
+			}
+			if (*p == 0x0a)
+				str_append(str, "<LF>");
+			else if (*p == 0x0d)
+				str_append(str, "<CR>");
+			else
+				str_printfa(str, "<0x%02x>", *p);
+		}
+	}
+	if (quote_open)
+		str_append_c(str, '\'');
+	return str_c(str);
 }
 
 static int http_response_parse(struct http_response_parser *parser)
@@ -122,7 +145,9 @@
 	case HTTP_RESPONSE_PARSE_STATE_VERSION:
 		if ((ret=http_message_parse_version(_parser)) <= 0) {
 			if (ret < 0)
-				_parser->error = "Invalid HTTP version in response";
+				_parser->error = t_strdup_printf(
+					"Invalid HTTP version in response: %s",
+					_reply_sanitize(_parser));
 			return ret;
 		}
 		parser->state = HTTP_RESPONSE_PARSE_STATE_SP1;
@@ -133,7 +158,7 @@
 		if (*_parser->cur != ' ') {
 			_parser->error = t_strdup_printf
 				("Expected ' ' after response version, but found %s",
-					_chr_sanitize(*_parser->cur));
+					_reply_sanitize(_parser));
 			return -1;
 		}
 		_parser->cur++;
@@ -155,7 +180,7 @@
 		if (*_parser->cur != ' ') {
 			_parser->error = t_strdup_printf
 				("Expected ' ' after response status code, but found %s",
-					_chr_sanitize(*_parser->cur));
+					_reply_sanitize(_parser));
 			return -1;
 		}
 		_parser->cur++;
@@ -183,7 +208,7 @@
 		if (*_parser->cur != '\n') {
 			_parser->error = t_strdup_printf
 				("Expected line end after response, but found %s",
-					_chr_sanitize(*_parser->cur));
+					_reply_sanitize(_parser));
 			return -1;
 		}
 		_parser->cur++;


More information about the dovecot-cvs mailing list