From 010a14140a255280e183e88050961cfce6f8d688 Mon Sep 17 00:00:00 2001 From: Timo Sirainen Date: Fri, 17 Aug 2018 14:12:25 +0300 Subject: [PATCH] lib-mail: rfc822-parser - Handle \ in quoted-string and domain-literal It was already handled in comments. Previously this caused the strings and domain-literals to be truncated at that position. --- src/lib-mail/rfc822-parser.c | 10 ++++++---- src/lib-mail/test-message-address.c | 14 ++++++++------ 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/lib-mail/rfc822-parser.c b/src/lib-mail/rfc822-parser.c index 8817b66962..bb73b8d76f 100644 --- a/src/lib-mail/rfc822-parser.c +++ b/src/lib-mail/rfc822-parser.c @@ -273,8 +273,9 @@ int rfc822_parse_quoted_string(struct rfc822_parser_context *ctx, string_t *str) if (ctx->data >= ctx->end) return -1; - if (*ctx->data == '\r' || *ctx->data == '\n') { - /* quoted-pair doesn't allow CR/LF. + if (*ctx->data == '\r' || *ctx->data == '\n' || + *ctx->data == '\0') { + /* quoted-pair doesn't allow CR/LF/NUL. They are part of the obs-qp though, so don't return them as error. */ ctx->data--; @@ -394,8 +395,9 @@ rfc822_parse_domain_literal(struct rfc822_parser_context *ctx, string_t *str) if (ctx->data >= ctx->end) return -1; - if (*ctx->data == '\r' || *ctx->data == '\n') { - /* quoted-pair doesn't allow CR/LF. + if (*ctx->data == '\r' || *ctx->data == '\n' || + *ctx->data == '\0') { + /* quoted-pair doesn't allow CR/LF/NUL. They are part of the obs-qp though, so don't return them as error. */ str_append_data(str, start, ctx->data - start); diff --git a/src/lib-mail/test-message-address.c b/src/lib-mail/test-message-address.c index 67a88b1bd7..3cb1b40d0d 100644 --- a/src/lib-mail/test-message-address.c +++ b/src/lib-mail/test-message-address.c @@ -325,10 +325,11 @@ static void test_message_address(void) static void test_message_address_nuls(void) { const unsigned char input[] = - "\"user\0nuls\"@[domain\0nuls] (comment\0nuls)"; + "\"user\0nuls\\\0-esc\"@[domain\0nuls\\\0-esc] (comment\0nuls\\\0-esc)"; const struct message_address output = { - NULL, "comment\xEF\xBF\xBDnuls", NULL, "user\xEF\xBF\xBDnuls", - "[domain\xEF\xBF\xBDnuls]", FALSE + NULL, "comment\xEF\xBF\xBDnuls\\\xEF\xBF\xBD-esc", NULL, + "user\xEF\xBF\xBDnuls\\\xEF\xBF\xBD-esc", + "[domain\xEF\xBF\xBDnuls\\\xEF\xBF\xBD-esc]", FALSE }; const struct message_address *addr; @@ -342,10 +343,11 @@ static void test_message_address_nuls(void) static void test_message_address_nuls_display_name(void) { const unsigned char input[] = - "\"displayname\0nuls\" <\"user\0nuls\"@[domain\0nuls]>"; + "\"displayname\0nuls\\\0-esc\" <\"user\0nuls\\\0-esc\"@[domain\0nuls\\\0-esc]>"; const struct message_address output = { - NULL, "displayname\xEF\xBF\xBDnuls", NULL, "user\xEF\xBF\xBDnuls", - "[domain\xEF\xBF\xBDnuls]", FALSE + NULL, "displayname\xEF\xBF\xBDnuls\\\xEF\xBF\xBD-esc", NULL, + "user\xEF\xBF\xBDnuls\\\xEF\xBF\xBD-esc", + "[domain\xEF\xBF\xBDnuls\\\xEF\xBF\xBD-esc]", FALSE }; const struct message_address *addr;