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