From: Timo Sirainen Date: Thu, 17 Jun 2004 21:28:23 +0000 (+0300) Subject: Added skip_initial_lwsp parameter to message_parse_header_init(). X-Git-Tag: 1.1.alpha1~3956 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2632143b0175c933bec1e59b5dc0811a095dc18d;p=thirdparty%2Fdovecot%2Fcore.git Added skip_initial_lwsp parameter to message_parse_header_init(). --HG-- branch : HEAD --- diff --git a/src/imap/imap-fetch-body-section.c b/src/imap/imap-fetch-body-section.c index 83e11fb5e8..e96afa059a 100644 --- a/src/imap/imap-fetch-body-section.c +++ b/src/imap/imap-fetch-body-section.c @@ -291,7 +291,7 @@ static int fetch_header_fields(struct istream *input, const char *section, ctx->dest_size = 0; - hdr_ctx = message_parse_header_init(input, NULL); + hdr_ctx = message_parse_header_init(input, NULL, FALSE); while ((hdr = message_parse_header_next(hdr_ctx)) != NULL) { /* see if we want this field. */ if (!ctx->match_func(ctx->fields, hdr->name, hdr->name_len)) diff --git a/src/lib-mail/message-body-search.c b/src/lib-mail/message-body-search.c index 6458b1897b..d9608371d1 100644 --- a/src/lib-mail/message-body-search.c +++ b/src/lib-mail/message-body-search.c @@ -115,7 +115,7 @@ static int message_search_header(struct part_search_context *ctx, /* we default to text content-type */ ctx->content_type_text = TRUE; - hdr_ctx = message_parse_header_init(input, NULL); + hdr_ctx = message_parse_header_init(input, NULL, TRUE); while ((hdr = message_parse_header_next(hdr_ctx)) != NULL) { if (hdr->eoh) continue; diff --git a/src/lib-mail/message-parser.c b/src/lib-mail/message-parser.c index 1e249a13c3..fc69531a95 100644 --- a/src/lib-mail/message-parser.c +++ b/src/lib-mail/message-parser.c @@ -41,6 +41,7 @@ struct message_header_parser_ctx { buffer_t *value_buf; size_t skip; + int skip_initial_lwsp; int has_nuls; }; @@ -214,7 +215,7 @@ static void message_parse_part_header(struct message_parser_ctx *parser_ctx) struct message_header_line *hdr; hdr_ctx = message_parse_header_init(parser_ctx->input, - &part->header_size); + &part->header_size, TRUE); while ((hdr = message_parse_header_next(hdr_ctx)) != NULL) { /* call the user-defined header parser */ if (parser_ctx->callback != NULL) @@ -634,7 +635,7 @@ void message_parse_header(struct message_part *part, struct istream *input, struct message_header_parser_ctx *hdr_ctx; struct message_header_line *hdr; - hdr_ctx = message_parse_header_init(input, hdr_size); + hdr_ctx = message_parse_header_init(input, hdr_size, TRUE); while ((hdr = message_parse_header_next(hdr_ctx)) != NULL) callback(part, hdr, context); message_parse_header_deinit(hdr_ctx); @@ -644,7 +645,8 @@ void message_parse_header(struct message_part *part, struct istream *input, } struct message_header_parser_ctx * -message_parse_header_init(struct istream *input, struct message_size *hdr_size) +message_parse_header_init(struct istream *input, struct message_size *hdr_size, + int skip_initial_lwsp) { struct message_header_parser_ctx *ctx; @@ -652,6 +654,7 @@ message_parse_header_init(struct istream *input, struct message_size *hdr_size) ctx->input = input; ctx->hdr_size = hdr_size; ctx->name = str_new(default_pool, 128); + ctx->skip_initial_lwsp = skip_initial_lwsp; if (hdr_size != NULL) memset(hdr_size, 0, sizeof(*hdr_size)); @@ -776,7 +779,6 @@ message_parse_header_next(struct message_header_parser_ctx *ctx) if (msg[i] <= ':') { if (msg[i] == ':') { colon_pos = i; - // FIXME: correct? line->full_value_offset = ctx->input->v_offset + i + 1; @@ -843,28 +845,37 @@ message_parse_header_next(struct message_header_parser_ctx *ctx) line->name = str_c(ctx->name); line->name_len = str_len(ctx->name); } else { - /* get value. skip all LWSP after ':'. Note that RFC2822 - doesn't say we should, but history behind it.. + size_t pos; - Exception to this is if the value consists only of LWSP, - then skip only the one LWSP after ':'. */ line->value = msg + colon_pos+1; line->value_len = size - colon_pos - 1; - while (line->value_len > 0 && IS_LWSP(line->value[0])) { - line->value++; - line->value_len--; - } + if (ctx->skip_initial_lwsp) { + /* get value. skip all LWSP after ':'. Note that + RFC2822 doesn't say we should, but history behind + it.. + + Exception to this is if the value consists only of + LWSP, then skip only the one LWSP after ':'. */ + for (pos = 0; pos < line->value_len; pos++) { + if (!IS_LWSP(line->value[0])) + break; + } - if (line->value_len == 0) { - /* everything was LWSP */ - line->value = msg + colon_pos+1; - line->value_len = size - colon_pos - 1; - if (line->value_len > 0 && IS_LWSP(line->value[0])) { - line->value++; - line->value_len--; + if (pos == line->value_len) { + /* everything was LWSP */ + if (line->value_len > 0 && + IS_LWSP(line->value[0])) + pos = 1; } + } else { + pos = line->value_len > 0 && + IS_LWSP(line->value[0]) ? 1 : 0; } + line->value += pos; + line->value_len -= pos; + line->full_value_offset += pos; + /* get name, skip LWSP before ':' */ while (colon_pos > 0 && IS_LWSP(msg[colon_pos-1])) colon_pos--; diff --git a/src/lib-mail/message-parser.h b/src/lib-mail/message-parser.h index d0be6159ac..508077a47c 100644 --- a/src/lib-mail/message-parser.h +++ b/src/lib-mail/message-parser.h @@ -47,7 +47,7 @@ struct message_header_line { const unsigned char *value; size_t value_len; - const unsigned char *full_value; // FIXME: should contain \n too + const unsigned char *full_value; size_t full_value_len; uoff_t name_offset, full_value_offset; @@ -96,8 +96,13 @@ void message_parser_parse_body(struct message_parser_ctx *ctx, message_body_callback_t *body_callback, void *context); +/* skip_initial_lwsp controls if we should skip LWSP after "header: ". + Note that there may not be the single whitespace after "header:", and that + "header : " is also possible. These two conditions can't be determined from + struct message_header_line. */ struct message_header_parser_ctx * -message_parse_header_init(struct istream *input, struct message_size *hdr_size); +message_parse_header_init(struct istream *input, struct message_size *hdr_size, + int skip_initial_lwsp); void message_parse_header_deinit(struct message_header_parser_ctx *ctx); /* Read and return next header line. */ diff --git a/src/lib-storage/index/index-mail-headers.c b/src/lib-storage/index/index-mail-headers.c index 8d570129d7..b4428f3ba0 100644 --- a/src/lib-storage/index/index-mail-headers.c +++ b/src/lib-storage/index/index-mail-headers.c @@ -458,7 +458,7 @@ static int parse_cached_headers(struct index_mail *mail, int idx) index_mail_parse_header_init(mail, idx_headers); - hdr_ctx = message_parse_header_init(istream, NULL); + hdr_ctx = message_parse_header_init(istream, NULL, TRUE); while ((hdr = message_parse_header_next(hdr_ctx)) != NULL) { if (!index_mail_parse_header(NULL, hdr, mail)) break; diff --git a/src/lib-storage/mail-save.c b/src/lib-storage/mail-save.c index cb10568d45..cdc758f24f 100644 --- a/src/lib-storage/mail-save.c +++ b/src/lib-storage/mail-save.c @@ -96,7 +96,7 @@ static int save_headers(struct istream *input, struct ostream *output, struct message_header_line *hdr; int ret = 0; - hdr_ctx = message_parse_header_init(input, NULL); + hdr_ctx = message_parse_header_init(input, NULL, FALSE); while ((hdr = message_parse_header_next(hdr_ctx)) != NULL) { ret = header_callback(hdr->name, write_func, context); if (ret <= 0) {