"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "src/lib-mail/message-header-parser.c" between
dovecot-2.3.16.tar.gz and dovecot-2.3.17.tar.gz

About: Dovecot is an IMAP and POP3 server, written with security primarily in mind.

message-header-parser.c  (dovecot-2.3.16):message-header-parser.c  (dovecot-2.3.17)
/* Copyright (c) 2002-2018 Dovecot authors, see the included COPYING file */ /* Copyright (c) 2002-2018 Dovecot authors, see the included COPYING file */
#include "lib.h" #include "lib.h"
#include "buffer.h" #include "buffer.h"
#include "istream.h" #include "istream.h"
#include "str.h" #include "str.h"
#include "strfuncs.h"
#include "unichar.h" #include "unichar.h"
#include "message-size.h" #include "message-size.h"
#include "message-header-parser.h" #include "message-header-parser.h"
/* RFC 5322 2.1.1 and 2.2 */
#define MESSAGE_HEADER_NAME_MAX_LEN 1000
struct message_header_parser_ctx { struct message_header_parser_ctx {
struct message_header_line line; struct message_header_line line;
struct istream *input; struct istream *input;
struct message_size *hdr_size; struct message_size *hdr_size;
string_t *name; string_t *name;
buffer_t *value_buf; buffer_t *value_buf;
enum message_header_parser_flags flags; enum message_header_parser_flags flags;
skipping to change at line 265 skipping to change at line 269
line->eoh = TRUE; line->eoh = TRUE;
line->name_len = line->value_len = line->full_value_len = 0; line->name_len = line->value_len = line->full_value_len = 0;
line->name = ""; line->value = line->full_value = NULL; line->name = ""; line->value = line->full_value = NULL;
line->middle = NULL; line->middle_len = 0; line->middle = NULL; line->middle_len = 0;
line->full_value_offset = line->name_offset; line->full_value_offset = line->name_offset;
line->continues = FALSE; line->continues = FALSE;
} else if (line->continued) { } else if (line->continued) {
line->value = msg; line->value = msg;
line->value_len = size; line->value_len = size;
} else if (colon_pos == UINT_MAX) { } else if (colon_pos == UINT_MAX) {
/* missing ':', assume the whole line is name */ /* missing ':', assume the whole line is value */
line->value = NULL; line->value = msg;
line->value_len = 0; line->value_len = size;
line->full_value_offset = line->name_offset;
str_truncate(ctx->name, 0);
buffer_append(ctx->name, msg, size);
line->name = str_c(ctx->name);
line->name_len = str_len(ctx->name);
line->middle = NULL; line->name = "";
line->name_len = 0;
line->middle = uchar_empty_ptr;
line->middle_len = 0; line->middle_len = 0;
} else { } else {
size_t pos; size_t pos;
line->value = msg + colon_pos+1; line->value = msg + colon_pos+1;
line->value_len = size - colon_pos - 1; line->value_len = size - colon_pos - 1;
if ((ctx->flags & MESSAGE_HEADER_PARSER_FLAG_SKIP_INITIAL_LWSP) ! = 0) { if ((ctx->flags & MESSAGE_HEADER_PARSER_FLAG_SKIP_INITIAL_LWSP) ! = 0) {
/* get value. skip all LWSP after ':'. Note that /* get value. skip all LWSP after ':'. Note that
RFC2822 doesn't say we should, but history behind RFC2822 doesn't say we should, but history behind
it.. it..
skipping to change at line 312 skipping to change at line 315
} }
line->value += pos; line->value += pos;
line->value_len -= pos; line->value_len -= pos;
line->full_value_offset += pos; line->full_value_offset += pos;
/* get name, skip LWSP before ':' */ /* get name, skip LWSP before ':' */
while (colon_pos > 0 && IS_LWSP(msg[colon_pos-1])) while (colon_pos > 0 && IS_LWSP(msg[colon_pos-1]))
colon_pos--; colon_pos--;
str_truncate(ctx->name, 0); /* Treat overlong header names as if the full header line was
/* use buffer_append() so the name won't be truncated if there a value. Callers can usually handle large values better than
are NULs. */ large names. */
buffer_append(ctx->name, msg, colon_pos); if (colon_pos > MESSAGE_HEADER_NAME_MAX_LEN) {
str_append_c(ctx->name, '\0'); line->name = "";
line->name_len = 0;
/* keep middle stored also in ctx->name so it's available line->middle = uchar_empty_ptr;
with use_full_value */ line->middle_len = 0;
line->middle = msg + colon_pos; line->value = msg;
line->middle_len = (size_t)(line->value - line->middle); line->value_len = size;
str_append_data(ctx->name, line->middle, line->middle_len); line->full_value_offset = line->name_offset;
} else {
line->name = str_c(ctx->name); str_truncate(ctx->name, 0);
line->name_len = colon_pos; /* use buffer_append() so the name won't be truncated if
line->middle = str_data(ctx->name) + line->name_len + 1; there
are NULs. */
buffer_append(ctx->name, msg, colon_pos);
str_append_c(ctx->name, '\0');
/* keep middle stored also in ctx->name so it's available
with use_full_value */
line->middle = msg + colon_pos;
line->middle_len = (size_t)(line->value - line->middle);
str_append_data(ctx->name, line->middle, line->middle_len
);
line->name = str_c(ctx->name);
line->name_len = colon_pos;
line->middle = str_data(ctx->name) + line->name_len + 1;
}
} }
if (!line->continued) { if (!line->continued) {
/* first header line. make a copy of the line since we can't /* first header line. make a copy of the line since we can't
really trust input stream not to lose it. */ really trust input stream not to lose it. */
buffer_append(ctx->value_buf, line->value, line->value_len); buffer_append(ctx->value_buf, line->value, line->value_len);
line->value = line->full_value = ctx->value_buf->data; line->value = line->full_value = ctx->value_buf->data;
line->full_value_len = line->value_len; line->full_value_len = line->value_len;
} else if (line->use_full_value) { } else if (line->use_full_value) {
/* continue saving the full value. */ /* continue saving the full value. */
skipping to change at line 437 skipping to change at line 453
rare so keep it simple */ rare so keep it simple */
string_t *str = str_new(pool, size+2); string_t *str = str_new(pool, size+2);
for (size_t i = 0; i < size; i++) { for (size_t i = 0; i < size; i++) {
if (data[i] != '\0') if (data[i] != '\0')
str_append_c(str, data[i]); str_append_c(str, data[i]);
else else
str_append(str, UNICODE_REPLACEMENT_CHAR_UTF8); str_append(str, UNICODE_REPLACEMENT_CHAR_UTF8);
} }
return str_c(str); return str_c(str);
} }
bool message_header_name_is_valid(const char *name)
{
/*
field-name = 1*ftext
ftext = %d33-57 / ; Printable US-ASCII
%d59-126 ; characters not including
; ":".
*/
for (unsigned int i = 0; name[i] != '\0'; i++) {
unsigned char c = name[i];
if (c >= 33 && c <= 57) {
/* before ":" */
} else if (c >= 59 && c <= 126) {
/* after ":" */
} else {
return FALSE;
}
}
return TRUE;
}
 End of changes. 6 change blocks. 
24 lines changed or deleted 42 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)