unsigned int add_missing_eoh:1;
unsigned int end_body_with_lf:1;
unsigned int last_lf_added:1;
+ unsigned int last_orig_crlf:1;
+ unsigned int last_added_newline:1;
unsigned int eoh_not_matched:1;
unsigned int prev_matched:1;
};
buffer_append(mstream->hdr_buf, "\r\n", 2);
else
buffer_append_c(mstream->hdr_buf, '\n');
+ mstream->last_orig_crlf = orig_crlf;
+ mstream->last_added_newline = TRUE;
}
static ssize_t hdr_stream_update_pos(struct header_filter_istream *mstream)
if (mstream->hdr_buf->used >= mstream->istream.max_buffer_size)
break;
}
+ if (mstream->hdr_buf->used > 0) {
+ const unsigned char *data = mstream->hdr_buf->data;
+ mstream->last_added_newline =
+ data[mstream->hdr_buf->used-1] == '\n';
+ }
if (hdr_ret < 0) {
if (mstream->istream.parent->stream_errno != 0) {
}
if (!mstream->seen_eoh && mstream->add_missing_eoh) {
mstream->seen_eoh = TRUE;
- add_eol(mstream, FALSE);
+ if (!mstream->last_added_newline)
+ add_eol(mstream, mstream->last_orig_crlf);
+ add_eol(mstream, mstream->last_orig_crlf);
}
}
test_end();
}
+static void test_istream_add_missing_eoh(void)
+{
+ struct {
+ const char *input;
+ const char *output;
+ unsigned int extra;
+ } tests[] = {
+ { "From: foo", "From: foo\n\n", 1 },
+ { "From: foo\n", "From: foo\n\n", 1 },
+ { "From: foo\n\n", "From: foo\n\n", 1 },
+ { "From: foo\n\nbar", "From: foo\n\nbar", 0 },
+ { "From: foo\r\n", "From: foo\r\n\r\n", 1 },
+ { "From: foo\r\n\r\n", "From: foo\r\n\r\n", 0 },
+ { "From: foo\r\n\r\nbar", "From: foo\r\n\r\nbar", 0 }
+ };
+ struct istream *istream, *filter;
+ unsigned int i;
+
+ test_begin("i_stream_create_header_filter(add_missing_eoh)");
+ for (i = 0; i < N_ELEMENTS(tests); i++) {
+ istream = test_istream_create(tests[i].input);
+ filter = i_stream_create_header_filter(istream,
+ HEADER_FILTER_EXCLUDE |
+ HEADER_FILTER_CRLF_PRESERVE |
+ HEADER_FILTER_ADD_MISSING_EOH,
+ NULL, 0,
+ *null_header_filter_callback, (void *)NULL);
+ test_istream_run(istream, filter,
+ strlen(tests[i].input) + tests[i].extra,
+ tests[i].output);
+ i_stream_unref(&filter);
+ i_stream_unref(&istream);
+ }
+ test_end();
+}
+
static void ATTR_NULL(3)
strip_eoh_callback(struct header_filter_istream *input ATTR_UNUSED,
struct message_header_line *hdr,
test_istream_filter_large_buffer,
test_istream_callbacks,
test_istream_edit,
+ test_istream_add_missing_eoh,
test_istream_end_body_with_lf,
test_istream_strip_eoh,
NULL