dovecot-2.2: imap-url: Fixed handling of ipath-empty syntax (bas...

dovecot at dovecot.org dovecot at dovecot.org
Fri Jun 27 14:41:47 UTC 2014


details:   http://hg.dovecot.org/dovecot-2.2/rev/3f9d15b600b1
changeset: 17537:3f9d15b600b1
user:      Stephan Bosch <stephan at rename-it.nl>
date:      Fri Jun 27 17:39:52 2014 +0300
description:
imap-url: Fixed handling of ipath-empty syntax (basically empty relative URLs).
This also normalizes Mailbox/ to Mailbox.
Initial indication reported by Coverity.

diffstat:

 src/lib-imap/imap-url.c      |  338 +++++++++++++++++++++---------------------
 src/lib-imap/test-imap-url.c |   75 ++++++++-
 src/lib/uri-util.c           |    6 +-
 3 files changed, 241 insertions(+), 178 deletions(-)

diffs (truncated from 547 to 300 lines):

diff -r 1abf8621981a -r 3f9d15b600b1 src/lib-imap/imap-url.c
--- a/src/lib-imap/imap-url.c	Fri Jun 27 17:37:56 2014 +0300
+++ b/src/lib-imap/imap-url.c	Fri Jun 27 17:39:52 2014 +0300
@@ -508,7 +508,7 @@
 		int rel = relative;
 
 		/* /;PARTIAL= */
-		if (base->have_partial && rel-- <= 0) {
+		if (base->have_partial && --rel <= 0) {
 			have_partial = base->have_partial;
 			partial_offset = base->partial_offset;
 			partial_size = base->partial_size;
@@ -528,7 +528,7 @@
 			}
 		}
 		/* /;UID= */
-		if (base->uid > 0 && rel-- <= 0) {
+		if (base->uid > 0 && --rel <= 0) {
 			uid = base->uid;
 		}
 		/* /mail/box;UIDVALIDITY= */
@@ -556,196 +556,198 @@
 	}
 
 	/* Scan for last mailbox-ref segment */
-	if (uid == 0) {
-		p = NULL;
-		while (*segment != NULL) {
-			/* ';' must be pct-encoded; if it is not, this is
-			   either the last mailbox-ref path segment containing
-			   ';UIDVALIDITY=' or the subsequent iuid ';UID=' path
-			   segment */
-			if ((p = strchr(*segment, ';')) != NULL)
-				break;
+	if (segment != NULL) {
+		if (relative == 0 || (!have_partial && section == NULL)) {
+			p = NULL;
+			while (*segment != NULL) {
+				/* ';' must be pct-encoded; if it is not, this is
+					 either the last mailbox-ref path segment containing
+					 ';UIDVALIDITY=' or the subsequent iuid ';UID=' path
+					 segment */
+				if ((p = strchr(*segment, ';')) != NULL)
+					break;
 
-			if (segment > path ||
-			    (!mailbox_endslash && str_len(mailbox) > 0))
-				str_append_c(mailbox, '/');
-			if (**segment != '\0') {
-				if (!uri_data_decode(parser, *segment, NULL, &value))
-					return -1;
-				str_append(mailbox, value);
-				mailbox_endslash = FALSE;
-			}
-			segment++;
-		}
-
-		/* Handle ';' */
-		if (p != NULL) {
-			/* [uidvalidity] */
-			if (strncasecmp(p, ";UIDVALIDITY=", 13) == 0) {
-				/* append last bit of mailbox */
-				if (segment > path ||
-				    (!mailbox_endslash && str_len(mailbox) > 0))
-					str_append_c(mailbox, '/');
-				if (*segment != p) {
-					if (!uri_data_decode(parser, *segment, p, &value))
+				if (**segment != '\0') {
+					if (segment > path ||
+							(!mailbox_endslash && str_len(mailbox) > 0))
+						str_append_c(mailbox, '/');
+					if (!uri_data_decode(parser, *segment, NULL, &value))
 						return -1;
 					str_append(mailbox, value);
+					mailbox_endslash = FALSE;
 				}
+				segment++;
+			}
 
-				/* ";UIDVALIDITY=" nz-number */
-				if (strchr(p+13, ';') != NULL) {
-					parser->error = "Encountered stray ';' after UIDVALIDITY";
+			/* Handle ';' */
+			if (p != NULL) {
+				/* [uidvalidity] */
+				if (strncasecmp(p, ";UIDVALIDITY=", 13) == 0) {
+					/* append last bit of mailbox */
+					if (*segment != p) {
+						if (segment > path ||
+								(!mailbox_endslash && str_len(mailbox) > 0))
+							str_append_c(mailbox, '/');
+						if (!uri_data_decode(parser, *segment, p, &value))
+							return -1;
+						str_append(mailbox, value);
+					}
+
+					/* ";UIDVALIDITY=" nz-number */
+					if (strchr(p+13, ';') != NULL) {
+						parser->error = "Encountered stray ';' after UIDVALIDITY";
+						return -1;
+					}
+
+					/* nz-number */
+					if (p[13] == '\0') {
+						parser->error = "Empty UIDVALIDITY value";
+						return -1;
+					}
+					if (imap_url_parse_number(parser, p+13, &uidvalidity) <= 0)
+						return -1;
+					if (uidvalidity == 0) {
+						parser->error = "UIDVALIDITY cannot be zero";
+						return -1;
+					}
+					segment++;
+				} else if (p != *segment) {
+					parser->error = "Encountered stray ';' in mailbox reference";
 					return -1;
 				}
-
-				/* nz-number */
-				if (p[13] == '\0') {
-					parser->error = "Empty UIDVALIDITY value";
-					return -1;
-				}
-				if (imap_url_parse_number(parser, p+13, &uidvalidity) <= 0)
-					return -1;
-				if (uidvalidity == 0) {
-					parser->error = "UIDVALIDITY cannot be zero";
-					return -1;
-				}
-				segment++;
-			} else if (p != *segment) {
-				parser->error = "Encountered stray ';' in mailbox reference";
-				return -1;
-			}
-		}
-
-		/* iuid */
-	 	if (*segment != NULL && strncasecmp(*segment, ";UID=", 5) == 0) {
-			/* ";UID=" nz-number */
-			value = (*segment)+5;
-			if ((p = strchr(value,';')) != NULL) {
-				if (segment[1] != NULL ) {
-					/* not the last segment, so it cannot be extension like iurlauth */
-					parser->error = "Encountered stray ';' in UID path segment";
-					return -1;
-				}
-				urlext = p;
-				value = t_strdup_until(value, p);
-			}
-			/* nz-number */
-			if (*value == '\0') {
-				parser->error = "Empty UID value";
-				return -1;
-			}
-			if (imap_url_parse_number(parser, value, &uid) <= 0)
-				return -1;
-			if (uid == 0) {
-				parser->error = "UID cannot be zero";
-				return -1;
-			}
-			segment++;
-		}
-	}
-
-	/* [isection] [ipartial] */
-	if (*segment != NULL && uid > 0 && !have_partial) {
-		/* [isection] */
-		if (section != NULL ||
-		    strncasecmp(*segment, ";SECTION=", 9) == 0) {
-			/* ";SECTION=" enc-section */
-			if (section == NULL) {
-				section = t_str_new(256);
-				value = (*segment) + 9;
-			} else {
-				value = *segment;
 			}
 
-			/* enc-section can contain slashes, so we merge path segments until one
-			   contains ';' */
-			while ((p = strchr(value,';')) == NULL) {
-				if (!section_endslash && str_len(section) > 0)
-					str_append_c(section, '/');
-				if (*value != '\0') {
-					if (!uri_data_decode(parser, value, NULL, &value))
-						return -1;
-					str_append(section, value);
-					section_endslash = FALSE;
-				}
-
-				segment++;
-				if (*segment == NULL)
-					break;
-				value = *segment;
-			}
-
-			if (p != NULL) {
-				/* found ';' */
-				if (p != value) {
-					/* it is not at the beginning of the path segment */
-					if (segment[1] != NULL) {
+			/* iuid */
+		 	if (*segment != NULL && strncasecmp(*segment, ";UID=", 5) == 0) {
+				/* ";UID=" nz-number */
+				value = (*segment)+5;
+				if ((p = strchr(value,';')) != NULL) {
+					if (segment[1] != NULL ) {
 						/* not the last segment, so it cannot be extension like iurlauth */
-						parser->error = "Encountered stray ';' in SECTION path segment";
+						parser->error = "Encountered stray ';' in UID path segment";
 						return -1;
 					}
 					urlext = p;
 					value = t_strdup_until(value, p);
+				}
+				/* nz-number */
+				if (*value == '\0') {
+					parser->error = "Empty UID value";
+					return -1;
+				}
+				if (imap_url_parse_number(parser, value, &uid) <= 0)
+					return -1;
+				if (uid == 0) {
+					parser->error = "UID cannot be zero";
+					return -1;
+				}
+				segment++;
+			}
+		}
+
+		/* [isection] [ipartial] */
+		if (*segment != NULL && uid > 0) {
+			/* [isection] */
+			if (section != NULL ||
+				  strncasecmp(*segment, ";SECTION=", 9) == 0) {
+				/* ";SECTION=" enc-section */
+				if (section == NULL) {
+					section = t_str_new(256);
+					value = (*segment) + 9;
+				} else {
+					value = *segment;
+				}
+
+				/* enc-section can contain slashes, so we merge path segments until one
+					 contains ';' */
+				while ((p = strchr(value,';')) == NULL) {
 					if (!section_endslash && str_len(section) > 0)
 						str_append_c(section, '/');
-					if (!uri_data_decode(parser, value, NULL, &value))
-						return -1;
-					str_append(section, value);
+					if (*value != '\0') {
+						if (!uri_data_decode(parser, value, NULL, &value))
+							return -1;
+						str_append(section, value);
+						section_endslash = FALSE;
+					}
+
 					segment++;
+					if (*segment == NULL)
+						break;
+					value = *segment;
+				}
+
+				if (p != NULL) {
+					/* found ';' */
+					if (p != value) {
+						/* it is not at the beginning of the path segment */
+						if (segment[1] != NULL) {
+							/* not the last segment, so it cannot be extension like iurlauth */
+							parser->error = "Encountered stray ';' in SECTION path segment";
+							return -1;
+						}
+						urlext = p;
+						value = t_strdup_until(value, p);
+						if (!section_endslash && str_len(section) > 0)
+							str_append_c(section, '/');
+						if (!uri_data_decode(parser, value, NULL, &value))
+							return -1;
+						str_append(section, value);
+						segment++;
+					}
+				}
+
+				if (str_len(section) == 0) {
+					parser->error = "Empty SECTION value";
+					return -1;
 				}
 			}
 
-			if (str_len(section) == 0) {
-				parser->error = "Empty SECTION value";
-				return -1;
+			/* [ipartial] */
+			if (*segment != NULL &&
+				  strncasecmp(*segment, ";PARTIAL=", 9) == 0) {
+				have_partial = TRUE;
+
+				/* ";PARTIAL=" partial-range */
+				value = (*segment) + 9;


More information about the dovecot-cvs mailing list