message-header-parser.c revision 6cb3c4f4276531258be706821e034f1f0a8cd276
c25356d5978632df6203437e1953bcb29e0c736fTimo Sirainen/* Copyright (c) 2002-2012 Dovecot authors, see the included COPYING file */
eb64c3586d854cddd693f0b811d897399076a441Timo Sirainenmessage_parse_header_init(struct istream *input, struct message_size *hdr_size,
32e1554df9abca74fef0af2ba2e4c37e90a06cd0Timo Sirainen ctx = i_new(struct message_header_parser_ctx, 1);
b337d3b6871b878d6467d7d8ed600433af5da5a1Timo Sirainen ctx->value_buf = buffer_create_dynamic(default_pool, 4096);
16db188cfddce117500a161302f17ae691b4500eTimo Sirainenvoid message_parse_header_deinit(struct message_header_parser_ctx **_ctx)
296dca49e4fe6046e0328c67ef1cf4b8077dec9cTimo Sirainen struct message_header_parser_ctx *ctx = *_ctx;
67c47dbb3fde79218320fd38a45c33f61bbf3012Timo Sirainenint message_parse_header_next(struct message_header_parser_ctx *ctx,
af3f857bb3166ed99595e11a9d18e5b5cc670e1aTimo Sirainen struct message_header_line *line = &ctx->line;
af3f857bb3166ed99595e11a9d18e5b5cc670e1aTimo Sirainen const unsigned char *msg;
af3f857bb3166ed99595e11a9d18e5b5cc670e1aTimo Sirainen size_t i, size, startpos, colon_pos, parse_size;
af3f857bb3166ed99595e11a9d18e5b5cc670e1aTimo Sirainen bool continued, continues, last_no_newline, last_crlf;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen /* new header line */
90804278df6586cceaf1b1b07a44713c01694048Timo Sirainen ret = i_stream_read_data(ctx->input, &msg, &size, startpos+1);
90804278df6586cceaf1b1b07a44713c01694048Timo Sirainen /* we want to know one byte in advance to find out
90804278df6586cceaf1b1b07a44713c01694048Timo Sirainen if it's multiline header */
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen /* header ended unexpectedly. */
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen /* error / EOF with no bytes */
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen (msg[0] == '\r' && size > 1 && msg[1] == '\n'))) {
ef50336eefcb9ba99f73c6af37420eaf8857a39bTimo Sirainen /* end of headers - this mostly happens just
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen with mbox where headers are read separately
9b706b345064ce8e8a657f54633f009a101298eaTimo Sirainen /* stream is nonblocking - need more data */
9b706b345064ce8e8a657f54633f009a101298eaTimo Sirainen /* a) line is larger than input buffer
9b706b345064ce8e8a657f54633f009a101298eaTimo Sirainen b) header ended unexpectedly */
32e1554df9abca74fef0af2ba2e4c37e90a06cd0Timo Sirainen if (colon_pos == UINT_MAX && ret == -2 && !continued) {
32e1554df9abca74fef0af2ba2e4c37e90a06cd0Timo Sirainen /* header name is huge. just skip it. */
957d09e495c33ad1180f82152e5e87e6b51ab04bTimo Sirainen /* go back to last LWSP if found. */
14b551180cb4ac7acac8b048d8d6d7278541d1f6Timo Sirainen /* we may or may not have a full header,
14b551180cb4ac7acac8b048d8d6d7278541d1f6Timo Sirainen but we don't know until we get the
e8490a52a1bc71bc53034e68f464435684ad810fTimo Sirainen next character. leave out the
size--;
size--;
colon_pos = i;
i = startpos;
for (; i < parse_size; i++) {
} else if (i < parse_size) {
startpos = 0;
size = i;
startpos = i;
if (size == 0) {
colon_pos--;
if (last_no_newline) {
if (last_crlf)
int ret;