--- dovecot-2.0-pure/src/lib-mail/message-parser.c 2010-08-08 10:05:30.000000000 +0200 +++ dovecot-2.0/src/lib-mail/message-parser.c 2010-08-26 10:01:57.000000000 +0200 @@ -81,26 +81,40 @@ { unsigned int missing_cr_count = 0; const unsigned char *data = block->data; - size_t i; + unsigned char *last, *curr; block->hdr = NULL; - for (i = 0; i < block->size; i++) { - if (data[i] <= '\n') { - if (data[i] == '\n') { - ctx->part->body_size.lines++; - if ((i > 0 && data[i-1] != '\r') || - (i == 0 && ctx->last_chr != '\r')) - missing_cr_count++; - } else if (data[i] == '\0') - ctx->part->flags |= MESSAGE_PART_FLAG_HAS_NULS; - } + /* check nuls */ + if (memchr(data, 0, block->size) != NULL) { + ctx->part->flags |= MESSAGE_PART_FLAG_HAS_NULS; + } + + /* count lines and missing cr (from begining + 1) */ + last = (unsigned char *)data + 1; + while (TRUE) { + curr = memchr(last, '\n', block->size - (last - data)); + if (curr == NULL) + break; + + ctx->part->body_size.lines++; + + if (*(curr - 1) != '\r') + missing_cr_count++; + + last = curr + 1; + } + + /* exceptional condition (test begining) */ + if (*data == '\n' && ctx->last_chr != '\r') { + ctx->part->body_size.lines++; + missing_cr_count++; } ctx->part->body_size.physical_size += block->size; ctx->part->body_size.virtual_size += block->size + missing_cr_count; - ctx->last_chr = data[i-1]; + ctx->last_chr = *(data + block->size - 1); ctx->skip += block->size; } @@ -196,6 +210,7 @@ const unsigned char *data, size_t size, bool full, struct message_boundary **boundary_r) { + unsigned char *ptr; size_t i; *boundary_r = NULL; @@ -215,10 +230,9 @@ } /* need to find the end of line */ - for (i = 2; i < size; i++) { - if (data[i] == '\n') - break; - } + ptr = (unsigned char *)memchr(data + 2, '\n', size - 2); + i = (ptr != NULL) ? ptr - data : size; + if (i == size && i < BOUNDARY_END_MAX_LEN && !ctx->input->eof && !full) { /* no LF found */ @@ -251,6 +265,7 @@ static int parse_next_body_skip_boundary_line(struct message_parser_ctx *ctx, struct message_block *block_r) { + unsigned char *ptr; size_t i; int ret; bool full; @@ -258,10 +273,8 @@ if ((ret = message_parser_read_more(ctx, block_r, &full)) <= 0) return ret; - for (i = 0; i < block_r->size; i++) { - if (block_r->data[i] == '\n') - break; - } + ptr = (unsigned char *)memchr(block_r->data, '\n', block_r->size); + i = (ptr != NULL) ? ptr - block_r->data : block_r->size; if (i == block_r->size) { parse_body_add_block(ctx, block_r); @@ -323,6 +336,7 @@ { struct message_boundary *boundary = NULL; const unsigned char *data; + unsigned char *last, *curr; size_t i, boundary_start; int ret; bool full; @@ -343,20 +357,26 @@ } i_assert(block_r->size > 0); - for (i = boundary_start = 0; i < block_r->size; i++) { + boundary_start = 0; + last = data; + while (TRUE) { /* skip to beginning of the next line. the first line was handled already. */ size_t next_line_idx = block_r->size; - for (; i < block_r->size; i++) { - if (data[i] == '\n') { - boundary_start = i; - if (i > 0 && data[i-1] == '\r') - boundary_start--; - next_line_idx = i + 1; - break; - } - } + curr = (unsigned char *)memchr(last, '\n', + block_r->size - (last - data)); + if (curr == NULL) + break; + + last = curr + 1; + i = (curr - data); + + boundary_start = i; + if (curr > data && *(curr - 1) == '\r') + boundary_start--; + next_line_idx = i + 1; + if (boundary_start != 0) { /* we can skip the first lines. input buffer can't be full anymore. */ @@ -378,7 +398,7 @@ } } - if (i >= block_r->size) { + if (curr == NULL) { /* the boundary wasn't found from this data block, we'll need more data. */ ret = 0;