message-header-parser.c revision 15362cdf9df29fef8795e865957e17ec027a9ebf
2454dfa32c93c20a8522c6ed42fe057baaac9f9aStephan Bosch/* Copyright (c) 2002-2008 Dovecot authors, see the included COPYING file */
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainenmessage_parse_header_init(struct istream *input, struct message_size *hdr_size,
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen ctx = i_new(struct message_header_parser_ctx, 1);
92f5ea24e989266539e97c6fe59ede0565aec6fdTimo Sirainenvoid message_parse_header_deinit(struct message_header_parser_ctx **_ctx)
fb79b36eb34532dbe67caf99eefe3660b8c841e0Timo Sirainen struct message_header_parser_ctx *ctx = *_ctx;
1c0020171b04d14adc4966ed963361abc9a86787Timo Sirainenint message_parse_header_next(struct message_header_parser_ctx *ctx,
1c0020171b04d14adc4966ed963361abc9a86787Timo Sirainen struct message_header_line *line = &ctx->line;
1c0020171b04d14adc4966ed963361abc9a86787Timo Sirainen const unsigned char *msg;
df8046c9a4f6bc2a478ad1e74504d50f3110c906Timo Sirainen size_t i, size, startpos, colon_pos, parse_size;
7000810786f2959f02cd6d2f4151a9eb61ff5db8Timo Sirainen bool continued, continues, last_no_newline, last_crlf;
df8046c9a4f6bc2a478ad1e74504d50f3110c906Timo Sirainen if (line->use_full_value && !line->continued) {
df8046c9a4f6bc2a478ad1e74504d50f3110c906Timo Sirainen /* save the first line */
abb5d20d3155db02a1afec4066d52707ba9d4e52Timo Sirainen /* new header line */
d6a7cb184cc882a90aa3d9312082e0029f354ff6Timo Sirainen ret = i_stream_read_data(ctx->input, &msg, &size, startpos+1);
d6a7cb184cc882a90aa3d9312082e0029f354ff6Timo Sirainen /* we want to know one byte in advance to find out
d6a7cb184cc882a90aa3d9312082e0029f354ff6Timo Sirainen if it's multiline header */
f5e8a76a128d4e92f0641135183c164fd5c5ce5eTimo Sirainen /* header ended unexpectedly. */
f5e8a76a128d4e92f0641135183c164fd5c5ce5eTimo Sirainen /* error / EOF with no bytes */
cc935aff970ed6c24d136cc560c7e705a49d536cTimo Sirainen /* stream is nonblocking - need more data */
cc935aff970ed6c24d136cc560c7e705a49d536cTimo Sirainen (msg[0] == '\r' && size > 1 && msg[1] == '\n')) {
cc935aff970ed6c24d136cc560c7e705a49d536cTimo Sirainen /* end of headers - this mostly happens just
cc935aff970ed6c24d136cc560c7e705a49d536cTimo Sirainen with mbox where headers are read separately
279c6b6d0b0a159c8533102e7e914db21dadcb03Timo Sirainen /* a) line is larger than input buffer
279c6b6d0b0a159c8533102e7e914db21dadcb03Timo Sirainen b) header ended unexpectedly */
387f9e3b4120273ad0213206a0e9cc2dc0e62ccaTimo Sirainen if (colon_pos == UINT_MAX && ret == -2 && !continued) {
27e859cee42654bff801ba96677cfc4e4e0108c7Timo Sirainen /* header name is huge. just skip it. */
632018810af689442569cbb0139c55868923ccfeTimo Sirainen /* go back to last LWSP if found. */
dea8bfa31729dbdde1b12718f1ef98fac4e99db9Timo Sirainen /* find ':' */
dea8bfa31729dbdde1b12718f1ef98fac4e99db9Timo Sirainen /* end of headers, or error */
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen /* find '\n' */
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen for (; i < parse_size; i++) {
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen /* got a line */
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen /* skipping a huge line */
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen /* missing CR */
6de0cbb4a498ce0519b0f28e221164ce8d39736aTimo Sirainen /* missing CR */
if (size == 0) {
colon_pos--;
if (last_no_newline) {
if (last_crlf)
int ret;