dovecot-2.2: uri-util: Fix handling of '..' and '.' segments in ...

dovecot at dovecot.org dovecot at dovecot.org
Thu Oct 11 00:02:28 EEST 2012


details:   http://hg.dovecot.org/dovecot-2.2/rev/f960ad98429c
changeset: 15193:f960ad98429c
user:      Stephan Bosch <stephan at rename-it.nl>
date:      Wed Oct 10 23:55:21 2012 +0300
description:
uri-util: Fix handling of '..' and '.' segments in URI paths.
As specified by RFC 3986

diffstat:

 src/lib/uri-util.c |  44 +++++++++++++++++++++++++++++++++-----------
 1 files changed, 33 insertions(+), 11 deletions(-)

diffs (89 lines):

diff -r e63a281eeff9 -r f960ad98429c src/lib/uri-util.c
--- a/src/lib/uri-util.c	Mon Oct 08 00:48:55 2012 +0300
+++ b/src/lib/uri-util.c	Wed Oct 10 23:55:21 2012 +0300
@@ -594,19 +594,24 @@
 int uri_parse_path(struct uri_parser *parser,
 		   int *relative_r, const char *const **path_r)
 {
+	const unsigned char *pbegin = parser->cur;
 	ARRAY_TYPE(const_string) segments;
-	const char *segment;
+	const char *segment = NULL;
 	unsigned int count;
 	int relative = 1;
 	int ret;
 
 	t_array_init(&segments, 16);
 
+	/* check for a leading '/' and indicate absolute path
+	   when it is present
+	 */
 	if (parser->cur < parser->end && *parser->cur == '/') {
 		parser->cur++;
 		relative = 0;
 	}
 	
+	/* parse first segment */
 	if ((ret = uri_parse_path_segment(parser, &segment)) < 0)
 		return -1;
 	
@@ -615,32 +620,49 @@
 			/* strip dot segments */
 			if (segment[0] == '.') {
 				if (segment[1] == '.') {
-					/* '..' -> pop last segment (if any) */
-					count = array_count(&segments);
-					if (count > 0) {
-						array_delete(&segments, count-1, 1);
-					} else if ( relative > 0 ) {
-						relative++;
+					if (segment[2] == '\0') {
+						/* '..' -> skip and... */
+						segment = NULL;
+
+						/* ... pop last segment (if any) */
+						count = array_count(&segments);
+						if (count > 0) {
+							array_delete(&segments, count-1, 1);
+						} else if ( relative > 0 ) {
+							relative++;
+						}
 					}
-				} else {
+				} else if (segment[1] == '\0') {
 					/* '.' -> skip */
+					segment = NULL;
 				}
-			} else {
-				array_append(&segments, &segment, 1);
 			}
 		} else {
 			segment = "";
+		}
+
+		if (segment != NULL)
 			array_append(&segments, &segment, 1);
-		}
 
 		if (parser->cur >= parser->end || *parser->cur != '/')
 			break;
 		parser->cur++;
 
+		/* parse next path segment */
 		if ((ret = uri_parse_path_segment(parser, &segment)) < 0)
 			return -1;
 	}
 
+	if (parser->cur == pbegin) {
+		/* path part of URI is missing */
+		return 0;
+	}
+
+	/* special treatment for a trailing '..' or '.' */
+	if (segment == NULL) {
+		segment = "";
+		array_append(&segments, &segment, 1);
+	}
 	array_append_zero(&segments);
 	*path_r = array_get(&segments, &count);
 	*relative_r = relative;


More information about the dovecot-cvs mailing list