dovecot-2.2: lib-imap: number parsing simplification and hardenning

dovecot at dovecot.org dovecot at dovecot.org
Wed Jul 2 15:23:20 UTC 2014


details:   http://hg.dovecot.org/dovecot-2.2/rev/59b6893fbf65
changeset: 17553:59b6893fbf65
user:      Phil Carmody <phil at dovecot.fi>
date:      Wed Jul 02 18:21:24 2014 +0300
description:
lib-imap: number parsing simplification and hardenning
The invalid string "4772185884" (2^32*10/9) will be misparsed as being valid.
In uint32_t's, 477218588 * 10 + 4 = 477218588
Many large ranges have this issue, 477218588x-858993459x, 954437176x-...

We have helper functions - use them.

Signed-off-by: Phil Carmody <phil at dovecot.fi>

diffstat:

 src/lib-imap/imap-url.c |  46 ++++++++--------------------------------------
 1 files changed, 8 insertions(+), 38 deletions(-)

diffs (75 lines):

diff -r 1d873182d5a8 -r 59b6893fbf65 src/lib-imap/imap-url.c
--- a/src/lib-imap/imap-url.c	Wed Jul 02 18:21:24 2014 +0300
+++ b/src/lib-imap/imap-url.c	Wed Jul 02 18:21:24 2014 +0300
@@ -128,9 +128,6 @@
 imap_url_parse_number(struct uri_parser *parser, const char *data,
 		      uint32_t *number_r)
 {
-	uint32_t number = 0;
-	const char *p = data;
-
 	/* [IMAP4] RFC3501, Section 9
 	 *
 	 * number          = 1*DIGIT
@@ -138,23 +135,11 @@
 	 *                   ; (0 <= n < 4,294,967,296)
 	 */
 
-	if (i_isdigit(*p)) {
-		do {
-			uint32_t prev = number;
-
-			number = number * 10 + (*p - '0');
-			if (number < prev) {
-				parser->error = "IMAP number is too high";
-				return -1;
-			}
-			p++;
-		} while (i_isdigit(*p));
-
-		if (*p == '\0') {
-			if (number_r != NULL)
-				*number_r = number;
+	if (i_isdigit(*data)) {
+		if (str_to_uint32(data, number_r) == 0)
 			return 1;
-		}
+		parser->error = "IMAP number is too high";
+		return -1;
 	}
 
 	parser->error = t_strdup_printf(
@@ -166,29 +151,14 @@
 imap_url_parse_offset(struct uri_parser *parser, const char *data,
 		      uoff_t *number_r)
 {
-	uoff_t number = 0;
-	const char *p = data;
-
 	/* Syntax for big (uoff_t) numbers. Not strictly IMAP syntax, but this
 	   is handled similarly for Dovecot IMAP FETCH BODY partial <.>
 	   implementation. */
-	if (i_isdigit(*p)) {
-		do {
-			uoff_t prev = number;
-
-			number = number * 10 + (*p - '0');
-			if (number < prev) {
-				parser->error = "IMAP number is too high";
-				return -1;
-			}
-			p++;
-		} while (i_isdigit(*p));
-
-		if (*p == '\0') {
-			if (number_r != NULL)
-				*number_r = number;
+	if (i_isdigit(*data)) {
+		if (str_to_uoff(data, number_r) == 0)
 			return 1;
-		}
+		parser->error = "IMAP number is too high";
+		return -1;
 	}
 
 	parser->error = t_strdup_printf(


More information about the dovecot-cvs mailing list