Mercurial > dovecot > original-hg > dovecot-1.2
diff src/lib-mail/message-parser.c @ 1534:676995d7c0ca HEAD
IMAP protocol doesn't allow server to send NULs to client. Send ascii #128
instead.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Wed, 04 Jun 2003 18:57:58 +0300 |
parents | d15bfc7cae1c |
children | 7ac153f21949 |
line wrap: on
line diff
--- a/src/lib-mail/message-parser.c Wed Jun 04 17:48:38 2003 +0300 +++ b/src/lib-mail/message-parser.c Wed Jun 04 18:57:58 2003 +0300 @@ -38,6 +38,8 @@ string_t *name; buffer_t *value_buf; size_t skip; + + int has_nuls; }; static struct message_part * @@ -46,12 +48,12 @@ static struct message_part * message_parse_body(struct istream *input, struct message_boundary *boundaries, - struct message_size *body_size); + struct message_size *body_size, int *has_nuls); static struct message_part * message_skip_boundary(struct istream *input, struct message_boundary *boundaries, - struct message_size *boundary_size); + struct message_size *boundary_size, int *has_nuls); static void message_size_add_part(struct message_size *dest, struct message_part *part) @@ -138,6 +140,7 @@ { struct message_part *parent_part, *next_part, *part; struct message_boundary *b; + int has_nuls; /* multipart message. add new boundary */ b = t_new(struct message_boundary, 1); @@ -155,7 +158,9 @@ /* skip the data before the first boundary */ parent_part = parser_ctx->part; next_part = message_skip_boundary(input, parser_ctx->boundaries, - &parent_part->body_size); + &parent_part->body_size, &has_nuls); + if (has_nuls) + parent_part->flags |= MESSAGE_PART_FLAG_HAS_NULS; /* now, parse the parts */ while (next_part == parent_part) { @@ -165,6 +170,11 @@ parser_ctx->part = part; next_part = message_parse_part(input, parser_ctx); + if ((part->flags & MESSAGE_PART_FLAG_HAS_NULS) != 0) { + /* it also belongs to parent */ + parent_part->flags |= MESSAGE_PART_FLAG_HAS_NULS; + } + /* update our size */ message_size_add_part(&parent_part->body_size, part); @@ -173,7 +183,10 @@ /* skip the boundary */ next_part = message_skip_boundary(input, parser_ctx->boundaries, - &parent_part->body_size); + &parent_part->body_size, + &has_nuls); + if (has_nuls) + parent_part->flags |= MESSAGE_PART_FLAG_HAS_NULS; } /* remove boundary */ @@ -192,6 +205,7 @@ struct message_header_line *hdr; struct message_part *next_part, *part; uoff_t hdr_size; + int has_nuls; hdr_ctx = message_parse_header_init(input, &parser_ctx->part->header_size); @@ -219,6 +233,8 @@ parser_ctx->callback(parser_ctx->part, NULL, parser_ctx->context); } + if (hdr_ctx->has_nuls) + parser_ctx->part->flags |= MESSAGE_PART_FLAG_HAS_NULS; message_parse_header_deinit(hdr_ctx); i_assert((parser_ctx->part->flags & MUTEX_FLAGS) != MUTEX_FLAGS); @@ -263,23 +279,35 @@ /* normal message, read until the next boundary */ part = parser_ctx->part; next_part = message_parse_body(input, parser_ctx->boundaries, - &part->body_size); + &part->body_size, &has_nuls); + if (has_nuls) + part->flags |= MESSAGE_PART_FLAG_HAS_NULS; + } + + if ((part->flags & MESSAGE_PART_FLAG_HAS_NULS) != 0 && + part->parent != NULL) { + /* it also belongs to parent */ + part->parent->flags |= MESSAGE_PART_FLAG_HAS_NULS; } return next_part; } static void message_skip_line(struct istream *input, - struct message_size *msg_size, int skip_lf) + struct message_size *msg_size, int skip_lf, + int *has_nuls) { const unsigned char *msg; size_t i, size, startpos; startpos = 0; + *has_nuls = FALSE; while (i_stream_read_data(input, &msg, &size, startpos) > 0) { for (i = startpos; i < size; i++) { - if (msg[i] == '\n') { + if (msg[i] == '\0') + *has_nuls = TRUE; + else if (msg[i] == '\n') { if (!skip_lf) { if (i > 0 && msg[i-1] == '\r') i--; @@ -336,7 +364,8 @@ static struct message_boundary * message_find_boundary(struct istream *input, struct message_boundary *boundaries, - struct message_size *msg_size, int skip_over) + struct message_size *msg_size, int skip_over, + int *has_nuls) { struct message_boundary *boundary; const unsigned char *msg; @@ -344,11 +373,15 @@ boundary = NULL; missing_cr_count = startpos = line_start = 0; + *has_nuls = FALSE; while (i_stream_read_data(input, &msg, &size, startpos) > 0) { for (i = startpos; i < size; i++) { - if (msg[i] != '\n') + if (msg[i] != '\n') { + if (msg[i] == '\0') + *has_nuls = TRUE; continue; + } if (line_start != (size_t)-1 && i >= line_start+2 && msg[line_start] == '-' && @@ -447,20 +480,22 @@ static struct message_part * message_parse_body(struct istream *input, struct message_boundary *boundaries, - struct message_size *msg_size) + struct message_size *msg_size, int *has_nuls) { struct message_boundary *boundary; struct message_size body_size; if (boundaries == NULL) { - message_get_body_size(input, &body_size, (uoff_t)-1, NULL); + message_get_body_size(input, &body_size, + (uoff_t)-1, NULL, has_nuls); message_size_add(msg_size, &body_size); - return NULL; + boundary = NULL; } else { boundary = message_find_boundary(input, boundaries, - msg_size, FALSE); - return boundary == NULL ? NULL : boundary->part; + msg_size, FALSE, has_nuls); } + + return boundary == NULL ? NULL : boundary->part; } /* skip data until next boundary is found. if it's end boundary, @@ -468,7 +503,7 @@ static struct message_part * message_skip_boundary(struct istream *input, struct message_boundary *boundaries, - struct message_size *boundary_size) + struct message_size *boundary_size, int *has_nuls) { struct message_boundary *boundary; const unsigned char *msg; @@ -476,7 +511,7 @@ int end_boundary; boundary = message_find_boundary(input, boundaries, - boundary_size, TRUE); + boundary_size, TRUE, has_nuls); if (boundary == NULL) return NULL; @@ -486,11 +521,12 @@ end_boundary = msg[0] == '-' && msg[1] == '-'; /* skip the rest of the line */ - message_skip_line(input, boundary_size, !end_boundary); + message_skip_line(input, boundary_size, !end_boundary, has_nuls); if (end_boundary) { /* skip the footer */ - return message_parse_body(input, boundary->next, boundary_size); + return message_parse_body(input, boundary->next, + boundary_size, has_nuls); } return boundary == NULL ? NULL : boundary->part; @@ -615,7 +651,7 @@ if (colon_pos == UINT_MAX) { /* header name is huge. just skip it. */ message_skip_line(ctx->input, ctx->hdr_size, - TRUE); + TRUE, &ctx->has_nuls); continue; } @@ -645,14 +681,21 @@ /* end of headers, or error */ break; } + + if (msg[i] == '\0') + ctx->has_nuls = TRUE; } } } /* find '\n' */ for (i = startpos; i < parse_size; i++) { - if (msg[i] == '\n') - break; + if (msg[i] <= '\n') { + if (msg[i] == '\n') + break; + if (msg[i] == '\0') + ctx->has_nuls = TRUE; + } } if (i < parse_size) {