Mercurial > dovecot > core-2.2
changeset 20868:82e8fc1b394f
lib: uri-util: Always fully check the syntax of percent encoding while parsing URI components.
author | Stephan Bosch <stephan@dovecot.fi> |
---|---|
date | Sun, 02 Oct 2016 14:14:48 +0200 |
parents | 32678cf64cd1 |
children | 7cadfa7cb8f7 |
files | src/lib/uri-util.c |
diffstat | 1 files changed, 48 insertions(+), 36 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib/uri-util.c Sun May 08 22:56:59 2016 +0200 +++ b/src/lib/uri-util.c Sun Oct 02 14:14:48 2016 +0200 @@ -597,33 +597,37 @@ int uri_parse_path_segment(struct uri_parser *parser, const char **segment_r) { - const unsigned char *p = parser->cur; + const unsigned char *first = parser->cur; + int ret; - while (p < parser->end) { - if (*p == '%') { - p++; - continue; + while (parser->cur < parser->end) { + if (*parser->cur == '%') { + unsigned char ch = 0; + if ((ret=uri_parse_pct_encoded(parser, &ch)) < 0) + return -1; + if (ret > 0) + continue; } - if ((*p & 0x80) != 0 || (_uri_char_lookup[*p] & CHAR_MASK_PCHAR) == 0) + if ((*parser->cur & 0x80) != 0 || + (_uri_char_lookup[*parser->cur] & CHAR_MASK_PCHAR) == 0) break; - p++; + parser->cur++; } - if (p < parser->end && - *p != '/' && *p != '?' && *p != '#' ) { + if (parser->cur < parser->end && + *parser->cur != '/' && *parser->cur != '?' && *parser->cur != '#' ) { parser->error = "Path component contains invalid character"; return -1; } - if (p == parser->cur) + if (first == parser->cur) return 0; if (segment_r != NULL) - *segment_r = p_strdup_until(parser->pool, parser->cur, p); - parser->cur = p; + *segment_r = p_strdup_until(parser->pool, first, parser->cur); return 1; } @@ -728,7 +732,8 @@ int uri_parse_query(struct uri_parser *parser, const char **query_r) { - const unsigned char *p = parser->cur; + const unsigned char *first = parser->cur; + int ret; /* RFC 3986: * @@ -736,35 +741,39 @@ * query = *( pchar / "/" / "?" ) * pchar = unreserved / pct-encoded / sub-delims / ":" / "@" */ - if (p >= parser->end || *p != '?') + if (parser->cur >= parser->end || *parser->cur != '?') return 0; - p++; + parser->cur++; - while (p < parser->end) { - if (*p == '%') { - p++; - continue; + while (parser->cur < parser->end) { + if (*parser->cur == '%') { + unsigned char ch = 0; + if ((ret=uri_parse_pct_encoded(parser, &ch)) < 0) + return -1; + if (ret > 0) + continue; } - if ((*p & 0x80) != 0 || (_uri_char_lookup[*p] & CHAR_MASK_QCHAR) == 0) + if ((*parser->cur & 0x80) != 0 || + (_uri_char_lookup[*parser->cur] & CHAR_MASK_QCHAR) == 0) break; - p++; + parser->cur++; } - if (p < parser->end && *p != '#') { + if (parser->cur < parser->end && *parser->cur != '#') { parser->error = "Query component contains invalid character"; return -1; } if (query_r != NULL) - *query_r = p_strdup_until(parser->pool, parser->cur+1, p); - parser->cur = p; + *query_r = p_strdup_until(parser->pool, first+1, parser->cur); return 1; } int uri_parse_fragment(struct uri_parser *parser, const char **fragment_r) { - const unsigned char *p = parser->cur; + const unsigned char *first = parser->cur; + int ret; /* RFC 3986: * @@ -773,29 +782,32 @@ * pchar = unreserved / pct-encoded / sub-delims / ":" / "@" */ - if (p >= parser->end || *p != '#') + if (parser->cur >= parser->end || *parser->cur != '#') return 0; - p++; + parser->cur++; - while (p < parser->end) { - if (*p == '%') { - p++; - continue; + while (parser->cur < parser->end) { + if (*parser->cur == '%') { + unsigned char ch = 0; + if ((ret=uri_parse_pct_encoded(parser, &ch)) < 0) + return -1; + if (ret > 0) + continue; } - if ((*p & 0x80) != 0 || (_uri_char_lookup[*p] & CHAR_MASK_QCHAR) == 0) + if ((*parser->cur & 0x80) != 0 || + (_uri_char_lookup[*parser->cur] & CHAR_MASK_QCHAR) == 0) break; - p++; + parser->cur++; } - if (p < parser->end) { + if (parser->cur < parser->end) { parser->error = "Fragment component contains invalid character"; return -1; } if (fragment_r != NULL) - *fragment_r = p_strdup_until(parser->pool, parser->cur+1, p); - parser->cur = p; + *fragment_r = p_strdup_until(parser->pool, first+1, parser->cur); return 1; }