File 0004-lib-mail-Make-sure-parsers-don-t-accidentally-go-muc.patch of Package dovecot22.openSUSE_Leap_42.3_Update
From e9b86842441a668b30796bff7d60828614570a1b Mon Sep 17 00:00:00 2001
From: Timo Sirainen <timo.sirainen@dovecot.fi>
Date: Fri, 22 Dec 2017 18:42:53 +0200
Subject: [PATCH 4/7] lib-mail: Make sure parsers don't accidentally go much
beyond end pointer
---
src/lib-mail/message-address.c | 18 +++++++++---------
src/lib-mail/message-date.c | 4 ++--
src/lib-mail/message-part-data.c | 2 +-
src/lib-mail/rfc2231-parser.c | 2 +-
src/lib-mail/rfc822-parser.c | 38 +++++++++++++++++++-------------------
5 files changed, 32 insertions(+), 32 deletions(-)
diff --git a/src/lib-mail/message-address.c b/src/lib-mail/message-address.c
index 787a26e..88d638a 100644
--- a/src/lib-mail/message-address.c
+++ b/src/lib-mail/message-address.c
@@ -84,7 +84,7 @@ static int parse_local_part(struct message_address_parser_context *ctx)
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 @@ static int parse_domain_list(struct message_address_parser_context *ctx)
/* 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 @@ static int parse_angle_addr(struct message_address_parser_context *ctx)
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 @@ static int parse_name_addr(struct message_address_parser_context *ctx)
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 @@ static int parse_addr_spec(struct message_address_parser_context *ctx)
/* 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 @@ static int parse_addr_spec(struct message_address_parser_context *ctx)
/* 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 @@ static int parse_group(struct message_address_parser_context *ctx)
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 @@ static int parse_group(struct message_address_parser_context *ctx)
}
}
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 @@ static int parse_address_list(struct message_address_parser_context *ctx,
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;
diff --git a/src/lib-mail/message-date.c b/src/lib-mail/message-date.c
index e6956b7..b67b21e 100644
--- a/src/lib-mail/message-date.c
+++ b/src/lib-mail/message-date.c
@@ -103,7 +103,7 @@ static int next_token(struct message_date_parser_context *ctx,
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 @@ message_date_parser_tokens(struct message_date_parser_context *ctx,
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);
diff --git a/src/lib-mail/message-part-data.c b/src/lib-mail/message-part-data.c
index 75651a2..7f13244 100644
--- a/src/lib-mail/message-part-data.c
+++ b/src/lib-mail/message-part-data.c
@@ -374,7 +374,7 @@ parse_content_language(struct message_part_data *data,
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);
diff --git a/src/lib-mail/rfc2231-parser.c b/src/lib-mail/rfc2231-parser.c
index f62326e..c65b798 100644
--- a/src/lib-mail/rfc2231-parser.c
+++ b/src/lib-mail/rfc2231-parser.c
@@ -59,7 +59,7 @@ int rfc2231_parse(struct rfc822_parser_context *ctx,
if (ret < 0) {
/* try to continue anyway.. */
broken = TRUE;
- if (ctx->data == ctx->end)
+ if (ctx->data >= ctx->end)
break;
ctx->data++;
continue;
diff --git a/src/lib-mail/rfc822-parser.c b/src/lib-mail/rfc822-parser.c
index edb07f5..4e7a86d 100644
--- a/src/lib-mail/rfc822-parser.c
+++ b/src/lib-mail/rfc822-parser.c
@@ -72,7 +72,7 @@ int rfc822_skip_comment(struct rfc822_parser_context *ctx)
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 @@ int rfc822_skip_comment(struct rfc822_parser_context *ctx)
ctx->data - start);
}
ctx->data++;
- return ctx->data != ctx->end;
+ return ctx->data < ctx->end ? 1 : 0;
}
break;
case '\\':
@@ -95,7 +95,7 @@ int rfc822_skip_comment(struct rfc822_parser_context *ctx)
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_comment(struct rfc822_parser_context *ctx)
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 @@ int rfc822_skip_lwsp(struct rfc822_parser_context *ctx)
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 @@ int rfc822_parse_atom(struct rfc822_parser_context *ctx, string_t *str)
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 @@ int rfc822_parse_dot_atom(struct rfc822_parser_context *ctx, string_t *str)
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 @@ int rfc822_parse_mime_token(struct rfc822_parser_context *ctx, string_t *str)
{
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 @@ int rfc822_parse_quoted_string(struct rfc822_parser_context *ctx, string_t *str)
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 @@ int rfc822_parse_quoted_string(struct rfc822_parser_context *ctx, string_t *str)
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 @@ rfc822_parse_atom_or_dot(struct rfc822_parser_context *ctx, string_t *str)
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 @@ int rfc822_parse_phrase(struct rfc822_parser_context *ctx, string_t *str)
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 @@ rfc822_parse_domain_literal(struct rfc822_parser_context *ctx, string_t *str)
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 @@ int rfc822_parse_content_param(struct rfc822_parser_context *ctx,
*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 @@ int rfc822_parse_content_param(struct rfc822_parser_context *ctx,
/* 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);
--
2.1.4