Mercurial > dovecot > core-2.2
changeset 22884:77577228fd8f
lib-mail: Make sure parsers don't accidentally go much beyond end pointer
author | Timo Sirainen <timo.sirainen@dovecot.fi> |
---|---|
date | Fri, 22 Dec 2017 18:42:53 +0200 |
parents | f578acb188d6 |
children | 9648a682f05a |
files | src/lib-mail/message-address.c src/lib-mail/message-date.c src/lib-mail/message-part-data.c src/lib-mail/rfc2231-parser.c src/lib-mail/rfc822-parser.c |
diffstat | 5 files changed, 32 insertions(+), 32 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-mail/message-address.c Fri Dec 22 18:36:55 2017 +0200 +++ b/src/lib-mail/message-address.c Fri Dec 22 18:42:53 2017 +0200 @@ -84,7 +84,7 @@ local-part = dot-atom / quoted-string / obs-local-part obs-local-part = word *("." word) */ - i_assert(ctx->parser.data != ctx->parser.end); + i_assert(ctx->parser.data < ctx->parser.end); str_truncate(ctx->str, 0); if (*ctx->parser.data == '"') @@ -117,7 +117,7 @@ /* obs-domain-list = "@" domain *(*(CFWS / "," ) [CFWS] "@" domain) */ str_truncate(ctx->str, 0); for (;;) { - if (ctx->parser.data == ctx->parser.end) + if (ctx->parser.data >= ctx->parser.end) return 0; if (*ctx->parser.data != '@') @@ -153,7 +153,7 @@ if (parse_domain_list(ctx) <= 0 || *ctx->parser.data != ':') { if (ctx->fill_missing) ctx->addr.route = "INVALID_ROUTE"; - if (ctx->parser.data == ctx->parser.end) + if (ctx->parser.data >= ctx->parser.end) return -1; /* try to continue anyway */ } else { @@ -203,7 +203,7 @@ ctx->addr.domain = "SYNTAX_ERROR"; ctx->addr.invalid_syntax = TRUE; } - return ctx->parser.data != ctx->parser.end; + return ctx->parser.data < ctx->parser.end ? 1 : 0; } static int parse_addr_spec(struct message_address_parser_context *ctx) @@ -211,7 +211,7 @@ /* addr-spec = local-part "@" domain */ int ret, ret2 = -2; - i_assert(ctx->parser.data != ctx->parser.end); + i_assert(ctx->parser.data < ctx->parser.end); str_truncate(ctx->parser.last_comment, 0); @@ -221,7 +221,7 @@ /* end of input or parsing local-part failed */ ctx->addr.invalid_syntax = TRUE; } - if (ret != 0 && ctx->parser.data != ctx->parser.end && + if (ret != 0 && ctx->parser.data < ctx->parser.end && *ctx->parser.data == '@') { ret2 = parse_domain(ctx); if (ret2 <= 0) @@ -317,7 +317,7 @@ if (parse_mailbox(ctx) <= 0) { /* broken mailbox - try to continue anyway. */ } - if (ctx->parser.data == ctx->parser.end || + if (ctx->parser.data >= ctx->parser.end || *ctx->parser.data != ',') break; ctx->parser.data++; @@ -328,7 +328,7 @@ } } if (ret >= 0) { - if (ctx->parser.data == ctx->parser.end || + if (ctx->parser.data >= ctx->parser.end || *ctx->parser.data != ';') ret = -1; else { @@ -368,7 +368,7 @@ max_addresses--; if ((ret = parse_address(ctx)) == 0) break; - if (ctx->parser.data == ctx->parser.end || + if (ctx->parser.data >= ctx->parser.end || *ctx->parser.data != ',') { ret = -1; break;
--- a/src/lib-mail/message-date.c Fri Dec 22 18:36:55 2017 +0200 +++ b/src/lib-mail/message-date.c Fri Dec 22 18:42:53 2017 +0200 @@ -103,7 +103,7 @@ int ret; str_truncate(ctx->str, 0); - ret = ctx->parser.data == ctx->parser.end ? 0 : + ret = ctx->parser.data >= ctx->parser.end ? 0 : rfc822_parse_atom(&ctx->parser, ctx->str); *value = str_data(ctx->str); @@ -205,7 +205,7 @@ tm.tm_min = (value[0]-'0') * 10 + (value[1]-'0'); /* [:ss] */ - if (ctx->parser.data != ctx->parser.end && + if (ctx->parser.data < ctx->parser.end && IS_TIME_SEP(*ctx->parser.data)) { ctx->parser.data++; rfc822_skip_lwsp(&ctx->parser);
--- a/src/lib-mail/message-part-data.c Fri Dec 22 18:36:55 2017 +0200 +++ b/src/lib-mail/message-part-data.c Fri Dec 22 18:42:53 2017 +0200 @@ -374,7 +374,7 @@ array_append(&langs, &lang, 1); str_truncate(str, 0); - if (parser.data == parser.end || *parser.data != ',') + if (parser.data >= parser.end || *parser.data != ',') break; parser.data++; rfc822_skip_lwsp(&parser);
--- a/src/lib-mail/rfc2231-parser.c Fri Dec 22 18:36:55 2017 +0200 +++ b/src/lib-mail/rfc2231-parser.c Fri Dec 22 18:42:53 2017 +0200 @@ -59,7 +59,7 @@ if (ret < 0) { /* try to continue anyway.. */ broken = TRUE; - if (ctx->data == ctx->end) + if (ctx->data >= ctx->end) break; ctx->data++; continue;
--- a/src/lib-mail/rfc822-parser.c Fri Dec 22 18:36:55 2017 +0200 +++ b/src/lib-mail/rfc822-parser.c Fri Dec 22 18:42:53 2017 +0200 @@ -72,7 +72,7 @@ str_truncate(ctx->last_comment, 0); start = ++ctx->data; - for (; ctx->data != ctx->end; ctx->data++) { + for (; ctx->data < ctx->end; ctx->data++) { switch (*ctx->data) { case '(': level++; @@ -84,7 +84,7 @@ ctx->data - start); } ctx->data++; - return ctx->data != ctx->end; + return ctx->data < ctx->end ? 1 : 0; } break; case '\\': @@ -95,7 +95,7 @@ start = ctx->data + 1; ctx->data++; - if (ctx->data == ctx->end) + if (ctx->data >= ctx->end) return -1; break; } @@ -107,7 +107,7 @@ int rfc822_skip_lwsp(struct rfc822_parser_context *ctx) { - for (; ctx->data != ctx->end;) { + for (; ctx->data < ctx->end;) { if (*ctx->data == ' ' || *ctx->data == '\t' || *ctx->data == '\r' || *ctx->data == '\n') { ctx->data++; @@ -120,7 +120,7 @@ if (rfc822_skip_comment(ctx) < 0) return -1; } - return ctx->data != ctx->end; + return ctx->data < ctx->end ? 1 : 0; } int rfc822_parse_atom(struct rfc822_parser_context *ctx, string_t *str) @@ -132,10 +132,10 @@ atext = ; Any character except controls, SP, and specials. */ - if (ctx->data == ctx->end || !IS_ATEXT(*ctx->data)) + if (ctx->data >= ctx->end || !IS_ATEXT(*ctx->data)) return -1; - for (start = ctx->data++; ctx->data != ctx->end; ctx->data++) { + for (start = ctx->data++; ctx->data < ctx->end; ctx->data++) { if (IS_ATEXT(*ctx->data)) continue; @@ -161,10 +161,10 @@ For RFC-822 compatibility allow LWSP around '.' */ - if (ctx->data == ctx->end || !IS_ATEXT(*ctx->data)) + if (ctx->data >= ctx->end || !IS_ATEXT(*ctx->data)) return -1; - for (start = ctx->data++; ctx->data != ctx->end; ) { + for (start = ctx->data++; ctx->data < ctx->end; ) { if (IS_ATEXT(*ctx->data)) { ctx->data++; continue; @@ -194,7 +194,7 @@ { const unsigned char *start; - for (start = ctx->data; ctx->data != ctx->end; ctx->data++) { + for (start = ctx->data; ctx->data < ctx->end; ctx->data++) { if (IS_ATEXT_NON_TSPECIAL(*ctx->data) || *ctx->data == '.') continue; @@ -215,7 +215,7 @@ i_assert(*ctx->data == '"'); ctx->data++; - for (start = ctx->data; ctx->data != ctx->end; ctx->data++) { + for (start = ctx->data; ctx->data < ctx->end; ctx->data++) { switch (*ctx->data) { case '"': str_append_n(str, start, ctx->data - start); @@ -231,7 +231,7 @@ break; case '\\': ctx->data++; - if (ctx->data == ctx->end) + if (ctx->data >= ctx->end) return -1; str_append_n(str, start, ctx->data - start - 1); @@ -257,7 +257,7 @@ The difference between this function and rfc822_parse_dot_atom() is that this doesn't just silently skip over all the whitespace. */ - for (start = ctx->data; ctx->data != ctx->end; ctx->data++) { + for (start = ctx->data; ctx->data < ctx->end; ctx->data++) { if (IS_ATEXT(*ctx->data) || *ctx->data == '.') continue; @@ -279,7 +279,7 @@ obs-phrase = word *(word / "." / CFWS) */ - if (ctx->data == ctx->end) + if (ctx->data >= ctx->end) return 0; if (*ctx->data == '.') return -1; @@ -317,10 +317,10 @@ i_assert(ctx->data < ctx->end); i_assert(*ctx->data == '['); - for (start = ctx->data; ctx->data != ctx->end; ctx->data++) { + for (start = ctx->data; ctx->data < ctx->end; ctx->data++) { if (*ctx->data == '\\') { ctx->data++; - if (ctx->data == ctx->end) + if (ctx->data >= ctx->end) break; } else if (*ctx->data == ']') { ctx->data++; @@ -389,7 +389,7 @@ *key_r = NULL; *value_r = NULL; - if (ctx->data == ctx->end) + if (ctx->data >= ctx->end) return 0; if (*ctx->data != ';') return -1; @@ -412,10 +412,10 @@ /* broken / no value */ } else if (*ctx->data == '"') { ret = rfc822_parse_quoted_string(ctx, tmp); - } else if (ctx->data != ctx->end && *ctx->data == '=') { + } else if (ctx->data < ctx->end && *ctx->data == '=') { /* workaround for broken input: name==?utf-8?b?...?= */ - while (ctx->data != ctx->end && *ctx->data != ';' && + while (ctx->data < ctx->end && *ctx->data != ';' && *ctx->data != ' ' && *ctx->data != '\t' && *ctx->data != '\r' && *ctx->data != '\n') { str_append_c(tmp, *ctx->data);