Skip to content

Commit

Permalink
lib-mail: Make sure parsers don't accidentally go much beyond end poi…
Browse files Browse the repository at this point in the history
…nter
  • Loading branch information
sirainen committed Feb 16, 2018
1 parent b72d864 commit e9b8684
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 32 deletions.
18 changes: 9 additions & 9 deletions src/lib-mail/message-address.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 == '"')
Expand Down Expand Up @@ -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 != '@')
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -203,15 +203,15 @@ 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)
{
/* 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);

Expand All @@ -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)
Expand Down Expand Up @@ -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++;
Expand All @@ -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 {
Expand Down Expand Up @@ -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;
Expand Down
4 changes: 2 additions & 2 deletions src/lib-mail/message-date.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion src/lib-mail/message-part-data.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion src/lib-mail/rfc2231-parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
38 changes: 19 additions & 19 deletions src/lib-mail/rfc822-parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -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++;
Expand All @@ -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 '\\':
Expand All @@ -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;
}
Expand All @@ -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++;
Expand All @@ -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)
Expand All @@ -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;

Expand All @@ -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;
Expand Down Expand Up @@ -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;

Expand All @@ -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);
Expand All @@ -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);
Expand All @@ -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;

Expand All @@ -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;
Expand Down Expand Up @@ -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++;
Expand Down Expand Up @@ -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;
Expand All @@ -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);
Expand Down

0 comments on commit e9b8684

Please sign in to comment.