bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2007-2018 Dovecot authors, see the included COPYING file */
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen#include "lib.h"
ef3ebb56989cb9b1b80edd133a091338e4206836Timo Sirainen#include "str.h"
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen#include "istream.h"
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen#include "message-header-parser.h"
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen#include "istream-header-filter.h"
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen#include "test-common.h"
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainenstruct run_ctx {
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen header_filter_callback *callback;
201ce62e1dc315e5dd5e59c24660ed0946343bbbTimo Sirainen unsigned int callback_call_count;
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen bool null_hdr_seen;
69eb1a17f443454e0b3025f86f428671ace06e89Josef 'Jeff' Sipek bool eoh_seen;
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen bool callback_called;
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen};
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainenstatic void run_callback(struct header_filter_istream *input,
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen struct message_header_line *hdr,
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen bool *matched, struct run_ctx *ctx)
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen{
201ce62e1dc315e5dd5e59c24660ed0946343bbbTimo Sirainen i_assert(!ctx->null_hdr_seen);
201ce62e1dc315e5dd5e59c24660ed0946343bbbTimo Sirainen
201ce62e1dc315e5dd5e59c24660ed0946343bbbTimo Sirainen ctx->callback_call_count++;
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen if (hdr == NULL)
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen ctx->null_hdr_seen = TRUE;
201ce62e1dc315e5dd5e59c24660ed0946343bbbTimo Sirainen else {
201ce62e1dc315e5dd5e59c24660ed0946343bbbTimo Sirainen i_assert(!ctx->eoh_seen);
201ce62e1dc315e5dd5e59c24660ed0946343bbbTimo Sirainen if (hdr->eoh)
201ce62e1dc315e5dd5e59c24660ed0946343bbbTimo Sirainen ctx->eoh_seen = TRUE;
201ce62e1dc315e5dd5e59c24660ed0946343bbbTimo Sirainen }
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen if (ctx->callback != NULL)
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen ctx->callback(input, hdr, matched, NULL);
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen ctx->callback_called = TRUE;
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen}
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen
75891a354ed229a4e56bbb0eceab75a0d1278687Josef 'Jeff' Sipekstatic inline void
75891a354ed229a4e56bbb0eceab75a0d1278687Josef 'Jeff' Sipektest_istream_run_prep(struct run_ctx *run_ctx,
75891a354ed229a4e56bbb0eceab75a0d1278687Josef 'Jeff' Sipek header_filter_callback *callback)
75891a354ed229a4e56bbb0eceab75a0d1278687Josef 'Jeff' Sipek{
75891a354ed229a4e56bbb0eceab75a0d1278687Josef 'Jeff' Sipek i_zero(run_ctx);
75891a354ed229a4e56bbb0eceab75a0d1278687Josef 'Jeff' Sipek run_ctx->callback = callback;
75891a354ed229a4e56bbb0eceab75a0d1278687Josef 'Jeff' Sipek run_ctx->null_hdr_seen = FALSE;
69eb1a17f443454e0b3025f86f428671ace06e89Josef 'Jeff' Sipek run_ctx->eoh_seen = FALSE;
75891a354ed229a4e56bbb0eceab75a0d1278687Josef 'Jeff' Sipek run_ctx->callback_called = FALSE;
75891a354ed229a4e56bbb0eceab75a0d1278687Josef 'Jeff' Sipek}
75891a354ed229a4e56bbb0eceab75a0d1278687Josef 'Jeff' Sipek
75891a354ed229a4e56bbb0eceab75a0d1278687Josef 'Jeff' Sipekstatic void
75891a354ed229a4e56bbb0eceab75a0d1278687Josef 'Jeff' Sipektest_istream_run_check(struct run_ctx *run_ctx,
75891a354ed229a4e56bbb0eceab75a0d1278687Josef 'Jeff' Sipek struct istream *filter,
75891a354ed229a4e56bbb0eceab75a0d1278687Josef 'Jeff' Sipek const char *output,
69eb1a17f443454e0b3025f86f428671ace06e89Josef 'Jeff' Sipek enum header_filter_flags flags,
75891a354ed229a4e56bbb0eceab75a0d1278687Josef 'Jeff' Sipek bool first,
75891a354ed229a4e56bbb0eceab75a0d1278687Josef 'Jeff' Sipek size_t *size_r)
75891a354ed229a4e56bbb0eceab75a0d1278687Josef 'Jeff' Sipek{
75891a354ed229a4e56bbb0eceab75a0d1278687Josef 'Jeff' Sipek const unsigned char *data;
75891a354ed229a4e56bbb0eceab75a0d1278687Josef 'Jeff' Sipek const struct stat *st;
75891a354ed229a4e56bbb0eceab75a0d1278687Josef 'Jeff' Sipek
75891a354ed229a4e56bbb0eceab75a0d1278687Josef 'Jeff' Sipek if (first)
75891a354ed229a4e56bbb0eceab75a0d1278687Josef 'Jeff' Sipek test_assert(run_ctx->null_hdr_seen);
75891a354ed229a4e56bbb0eceab75a0d1278687Josef 'Jeff' Sipek else
75891a354ed229a4e56bbb0eceab75a0d1278687Josef 'Jeff' Sipek test_assert(run_ctx->null_hdr_seen == run_ctx->callback_called);
75891a354ed229a4e56bbb0eceab75a0d1278687Josef 'Jeff' Sipek
69eb1a17f443454e0b3025f86f428671ace06e89Josef 'Jeff' Sipek if (first && ((flags & HEADER_FILTER_ADD_MISSING_EOH) != 0))
69eb1a17f443454e0b3025f86f428671ace06e89Josef 'Jeff' Sipek test_assert(run_ctx->eoh_seen);
69eb1a17f443454e0b3025f86f428671ace06e89Josef 'Jeff' Sipek
75891a354ed229a4e56bbb0eceab75a0d1278687Josef 'Jeff' Sipek data = i_stream_get_data(filter, size_r);
75891a354ed229a4e56bbb0eceab75a0d1278687Josef 'Jeff' Sipek test_assert(*size_r == strlen(output) &&
75891a354ed229a4e56bbb0eceab75a0d1278687Josef 'Jeff' Sipek memcmp(data, output, *size_r) == 0);
75891a354ed229a4e56bbb0eceab75a0d1278687Josef 'Jeff' Sipek
75891a354ed229a4e56bbb0eceab75a0d1278687Josef 'Jeff' Sipek test_assert(i_stream_stat(filter, TRUE, &st) == 0 &&
75891a354ed229a4e56bbb0eceab75a0d1278687Josef 'Jeff' Sipek (uoff_t)st->st_size == *size_r);
75891a354ed229a4e56bbb0eceab75a0d1278687Josef 'Jeff' Sipek}
75891a354ed229a4e56bbb0eceab75a0d1278687Josef 'Jeff' Sipek
adb90447f6bf7b11b5fca7e87a3f256622fdef9fTimo Sirainenstatic void
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainentest_istream_run(struct istream *test_istream,
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen unsigned int input_len, const char *output,
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen enum header_filter_flags flags,
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen header_filter_callback *callback)
adb90447f6bf7b11b5fca7e87a3f256622fdef9fTimo Sirainen{
75891a354ed229a4e56bbb0eceab75a0d1278687Josef 'Jeff' Sipek struct run_ctx run_ctx;
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen struct istream *filter;
201ce62e1dc315e5dd5e59c24660ed0946343bbbTimo Sirainen unsigned int i, orig_callback_call_count;
adb90447f6bf7b11b5fca7e87a3f256622fdef9fTimo Sirainen size_t size;
adb90447f6bf7b11b5fca7e87a3f256622fdef9fTimo Sirainen
75891a354ed229a4e56bbb0eceab75a0d1278687Josef 'Jeff' Sipek test_istream_run_prep(&run_ctx, callback);
75891a354ed229a4e56bbb0eceab75a0d1278687Josef 'Jeff' Sipek
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen filter = i_stream_create_header_filter(test_istream, flags, NULL, 0,
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen run_callback, &run_ctx);
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen
adb90447f6bf7b11b5fca7e87a3f256622fdef9fTimo Sirainen for (i = 1; i < input_len; i++) {
adb90447f6bf7b11b5fca7e87a3f256622fdef9fTimo Sirainen test_istream_set_size(test_istream, i);
adb90447f6bf7b11b5fca7e87a3f256622fdef9fTimo Sirainen test_assert(i_stream_read(filter) >= 0);
adb90447f6bf7b11b5fca7e87a3f256622fdef9fTimo Sirainen }
adb90447f6bf7b11b5fca7e87a3f256622fdef9fTimo Sirainen test_istream_set_size(test_istream, input_len);
adb90447f6bf7b11b5fca7e87a3f256622fdef9fTimo Sirainen test_assert(i_stream_read(filter) > 0);
adb90447f6bf7b11b5fca7e87a3f256622fdef9fTimo Sirainen test_assert(i_stream_read(filter) == -1);
adb90447f6bf7b11b5fca7e87a3f256622fdef9fTimo Sirainen
69eb1a17f443454e0b3025f86f428671ace06e89Josef 'Jeff' Sipek test_istream_run_check(&run_ctx, filter, output, flags, TRUE, &size);
201ce62e1dc315e5dd5e59c24660ed0946343bbbTimo Sirainen orig_callback_call_count = run_ctx.callback_call_count;
adb90447f6bf7b11b5fca7e87a3f256622fdef9fTimo Sirainen
adb90447f6bf7b11b5fca7e87a3f256622fdef9fTimo Sirainen /* run again to make sure it's still correct the second time */
75891a354ed229a4e56bbb0eceab75a0d1278687Josef 'Jeff' Sipek test_istream_run_prep(&run_ctx, callback);
75891a354ed229a4e56bbb0eceab75a0d1278687Josef 'Jeff' Sipek
adb90447f6bf7b11b5fca7e87a3f256622fdef9fTimo Sirainen i_stream_skip(filter, size);
adb90447f6bf7b11b5fca7e87a3f256622fdef9fTimo Sirainen i_stream_seek(filter, 0);
adb90447f6bf7b11b5fca7e87a3f256622fdef9fTimo Sirainen while (i_stream_read(filter) > 0) ;
69eb1a17f443454e0b3025f86f428671ace06e89Josef 'Jeff' Sipek test_istream_run_check(&run_ctx, filter, output, flags, FALSE, &size);
201ce62e1dc315e5dd5e59c24660ed0946343bbbTimo Sirainen test_assert(run_ctx.callback_call_count == 0 ||
201ce62e1dc315e5dd5e59c24660ed0946343bbbTimo Sirainen run_ctx.callback_call_count == orig_callback_call_count);
201ce62e1dc315e5dd5e59c24660ed0946343bbbTimo Sirainen
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen i_stream_unref(&filter);
adb90447f6bf7b11b5fca7e87a3f256622fdef9fTimo Sirainen}
adb90447f6bf7b11b5fca7e87a3f256622fdef9fTimo Sirainen
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainenstatic void ATTR_NULL(3)
f7ec15aefabeb0a17d1f262bc5e9a15e43dfc5adTimo Sirainenfilter_callback(struct header_filter_istream *input ATTR_UNUSED,
f7ec15aefabeb0a17d1f262bc5e9a15e43dfc5adTimo Sirainen struct message_header_line *hdr,
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainen bool *matched, void *context ATTR_UNUSED)
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen{
0989e8ba44ec35dc9322e424b5213b96596319e7Timo Sirainen if (hdr != NULL && (hdr->name_offset == 0 ||
0989e8ba44ec35dc9322e424b5213b96596319e7Timo Sirainen strcmp(hdr->name, "X-Drop") == 0)) {
0989e8ba44ec35dc9322e424b5213b96596319e7Timo Sirainen /* drop 1) first header, 2) X-Drop header */
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen *matched = TRUE;
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen }
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen}
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainenstatic void test_istream_filter(void)
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen{
2719970c2c246f976178da179deeb64eecaec5baTimo Sirainen static const char *exclude_headers[] = { "Subject", "To" };
0989e8ba44ec35dc9322e424b5213b96596319e7Timo Sirainen const char *input = "From: foo\nFrom: abc\nTo: bar\nSubject: plop\nX-Drop: 1\n\nhello world\n";
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen const char *output = "From: abc\n\nhello world\n";
4334b9b032298defd4d3906f5357698ff016ead0Timo Sirainen struct istream *istream, *filter, *filter2;
2ac5f36aa7c2e7a07ba8815d43a6d7483f62e74cTimo Sirainen unsigned int i;
2ac5f36aa7c2e7a07ba8815d43a6d7483f62e74cTimo Sirainen size_t input_len = strlen(input);
2ac5f36aa7c2e7a07ba8815d43a6d7483f62e74cTimo Sirainen size_t output_len = strlen(output);
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen const unsigned char *data;
c8e34785671d3b13f4500144a2ec7af968ce3307Timo Sirainen const struct stat *st;
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen size_t size;
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen
6e81d67a4e8985d35034eab791e270ffc01800b8Timo Sirainen test_begin("i_stream_create_header_filter: exclude");
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen istream = test_istream_create(input);
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen filter = i_stream_create_header_filter(istream,
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen HEADER_FILTER_EXCLUDE |
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen HEADER_FILTER_NO_CR,
2719970c2c246f976178da179deeb64eecaec5baTimo Sirainen exclude_headers,
2719970c2c246f976178da179deeb64eecaec5baTimo Sirainen N_ELEMENTS(exclude_headers),
677b75f90d81eafe742896d6570a2f63ce501d05Josef 'Jeff' Sipek filter_callback, NULL);
4334b9b032298defd4d3906f5357698ff016ead0Timo Sirainen filter2 = i_stream_create_header_filter(filter,
4334b9b032298defd4d3906f5357698ff016ead0Timo Sirainen HEADER_FILTER_EXCLUDE |
4334b9b032298defd4d3906f5357698ff016ead0Timo Sirainen HEADER_FILTER_NO_CR,
2719970c2c246f976178da179deeb64eecaec5baTimo Sirainen exclude_headers,
2719970c2c246f976178da179deeb64eecaec5baTimo Sirainen N_ELEMENTS(exclude_headers),
27a44fcfd8d19bffe0f267f20a2b5d3fe7600fddTimo Sirainen *null_header_filter_callback,
677b75f90d81eafe742896d6570a2f63ce501d05Josef 'Jeff' Sipek NULL);
4334b9b032298defd4d3906f5357698ff016ead0Timo Sirainen i_stream_unref(&filter);
4334b9b032298defd4d3906f5357698ff016ead0Timo Sirainen filter = filter2;
4334b9b032298defd4d3906f5357698ff016ead0Timo Sirainen
4334b9b032298defd4d3906f5357698ff016ead0Timo Sirainen for (i = 1; i < input_len; i++) {
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen test_istream_set_size(istream, i);
4334b9b032298defd4d3906f5357698ff016ead0Timo Sirainen test_assert(i_stream_read(filter) >= 0);
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen }
4334b9b032298defd4d3906f5357698ff016ead0Timo Sirainen test_istream_set_size(istream, input_len);
4334b9b032298defd4d3906f5357698ff016ead0Timo Sirainen test_assert(i_stream_read(filter) > 0);
4334b9b032298defd4d3906f5357698ff016ead0Timo Sirainen test_assert(i_stream_read(filter) == -1);
4334b9b032298defd4d3906f5357698ff016ead0Timo Sirainen
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen data = i_stream_get_data(filter, &size);
4334b9b032298defd4d3906f5357698ff016ead0Timo Sirainen test_assert(size == output_len && memcmp(data, output, size) == 0);
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen
c8e34785671d3b13f4500144a2ec7af968ce3307Timo Sirainen test_assert(i_stream_stat(filter, TRUE, &st) == 0 &&
c8e34785671d3b13f4500144a2ec7af968ce3307Timo Sirainen (uoff_t)st->st_size == size);
c8e34785671d3b13f4500144a2ec7af968ce3307Timo Sirainen
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen i_stream_skip(filter, size);
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen i_stream_seek(filter, 0);
8bb360f9e5de1c25e4f875205bb06e8bf15dae14Timo Sirainen while (i_stream_read(filter) > 0) ;
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen data = i_stream_get_data(filter, &size);
4334b9b032298defd4d3906f5357698ff016ead0Timo Sirainen test_assert(size == output_len && memcmp(data, output, size) == 0);
c8e34785671d3b13f4500144a2ec7af968ce3307Timo Sirainen test_assert(i_stream_stat(filter, TRUE, &st) == 0 &&
c8e34785671d3b13f4500144a2ec7af968ce3307Timo Sirainen (uoff_t)st->st_size == size);
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen i_stream_unref(&filter);
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen i_stream_unref(&istream);
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen
4334b9b032298defd4d3906f5357698ff016ead0Timo Sirainen test_end();
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen}
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen
76a71915c6452a4bee9a8ae89ddbdf58fa941deeTimo Sirainenstatic void add_random_text(string_t *dest, unsigned int count)
76a71915c6452a4bee9a8ae89ddbdf58fa941deeTimo Sirainen{
76a71915c6452a4bee9a8ae89ddbdf58fa941deeTimo Sirainen unsigned int i;
76a71915c6452a4bee9a8ae89ddbdf58fa941deeTimo Sirainen
76a71915c6452a4bee9a8ae89ddbdf58fa941deeTimo Sirainen for (i = 0; i < count; i++)
191153d1a5b0eb0c129139570e3aa5212f28d2acJosef 'Jeff' Sipek str_append_c(dest, i_rand_minmax('a', 'z'));
76a71915c6452a4bee9a8ae89ddbdf58fa941deeTimo Sirainen}
76a71915c6452a4bee9a8ae89ddbdf58fa941deeTimo Sirainen
76a71915c6452a4bee9a8ae89ddbdf58fa941deeTimo Sirainenstatic void ATTR_NULL(3)
76a71915c6452a4bee9a8ae89ddbdf58fa941deeTimo Sirainenfilter2_callback(struct header_filter_istream *input ATTR_UNUSED,
76a71915c6452a4bee9a8ae89ddbdf58fa941deeTimo Sirainen struct message_header_line *hdr,
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen bool *matched, bool *null_hdr_seen)
76a71915c6452a4bee9a8ae89ddbdf58fa941deeTimo Sirainen{
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen if (hdr == NULL)
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen *null_hdr_seen = TRUE;
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen else if (strcmp(hdr->name, "To") == 0)
76a71915c6452a4bee9a8ae89ddbdf58fa941deeTimo Sirainen *matched = TRUE;
76a71915c6452a4bee9a8ae89ddbdf58fa941deeTimo Sirainen}
76a71915c6452a4bee9a8ae89ddbdf58fa941deeTimo Sirainen
76a71915c6452a4bee9a8ae89ddbdf58fa941deeTimo Sirainenstatic void test_istream_filter_large_buffer(void)
76a71915c6452a4bee9a8ae89ddbdf58fa941deeTimo Sirainen{
76a71915c6452a4bee9a8ae89ddbdf58fa941deeTimo Sirainen string_t *input, *output;
76a71915c6452a4bee9a8ae89ddbdf58fa941deeTimo Sirainen struct istream *istream, *filter;
c8e34785671d3b13f4500144a2ec7af968ce3307Timo Sirainen const struct stat *st;
76a71915c6452a4bee9a8ae89ddbdf58fa941deeTimo Sirainen const unsigned char *data;
76a71915c6452a4bee9a8ae89ddbdf58fa941deeTimo Sirainen size_t size, prefix_len;
76a71915c6452a4bee9a8ae89ddbdf58fa941deeTimo Sirainen const char *p;
76a71915c6452a4bee9a8ae89ddbdf58fa941deeTimo Sirainen unsigned int i;
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen bool null_hdr_seen = FALSE;
76a71915c6452a4bee9a8ae89ddbdf58fa941deeTimo Sirainen
6e81d67a4e8985d35034eab791e270ffc01800b8Timo Sirainen test_begin("i_stream_create_header_filter: large buffer");
76a71915c6452a4bee9a8ae89ddbdf58fa941deeTimo Sirainen
76a71915c6452a4bee9a8ae89ddbdf58fa941deeTimo Sirainen input = str_new(default_pool, 1024*128);
76a71915c6452a4bee9a8ae89ddbdf58fa941deeTimo Sirainen output = str_new(default_pool, 1024*128);
76a71915c6452a4bee9a8ae89ddbdf58fa941deeTimo Sirainen str_append(input, "From: ");
76a71915c6452a4bee9a8ae89ddbdf58fa941deeTimo Sirainen add_random_text(input, 1024*31);
76a71915c6452a4bee9a8ae89ddbdf58fa941deeTimo Sirainen str_append(input, "\nTo: ");
76a71915c6452a4bee9a8ae89ddbdf58fa941deeTimo Sirainen add_random_text(input, 1024*32);
76a71915c6452a4bee9a8ae89ddbdf58fa941deeTimo Sirainen str_append(input, "\nSubject: ");
76a71915c6452a4bee9a8ae89ddbdf58fa941deeTimo Sirainen add_random_text(input, 1024*34);
76a71915c6452a4bee9a8ae89ddbdf58fa941deeTimo Sirainen str_append(input, "\n\nbody\n");
76a71915c6452a4bee9a8ae89ddbdf58fa941deeTimo Sirainen
76a71915c6452a4bee9a8ae89ddbdf58fa941deeTimo Sirainen istream = test_istream_create_data(str_data(input), str_len(input));
76a71915c6452a4bee9a8ae89ddbdf58fa941deeTimo Sirainen test_istream_set_max_buffer_size(istream, 8192);
76a71915c6452a4bee9a8ae89ddbdf58fa941deeTimo Sirainen
76a71915c6452a4bee9a8ae89ddbdf58fa941deeTimo Sirainen filter = i_stream_create_header_filter(istream,
76a71915c6452a4bee9a8ae89ddbdf58fa941deeTimo Sirainen HEADER_FILTER_EXCLUDE |
76a71915c6452a4bee9a8ae89ddbdf58fa941deeTimo Sirainen HEADER_FILTER_NO_CR,
76a71915c6452a4bee9a8ae89ddbdf58fa941deeTimo Sirainen NULL, 0,
76a71915c6452a4bee9a8ae89ddbdf58fa941deeTimo Sirainen filter2_callback,
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen &null_hdr_seen);
76a71915c6452a4bee9a8ae89ddbdf58fa941deeTimo Sirainen
76a71915c6452a4bee9a8ae89ddbdf58fa941deeTimo Sirainen for (i = 0; i < 2; i++) {
76a71915c6452a4bee9a8ae89ddbdf58fa941deeTimo Sirainen for (;;) {
76a71915c6452a4bee9a8ae89ddbdf58fa941deeTimo Sirainen ssize_t ret = i_stream_read(filter);
76a71915c6452a4bee9a8ae89ddbdf58fa941deeTimo Sirainen i_assert(ret != 0);
76a71915c6452a4bee9a8ae89ddbdf58fa941deeTimo Sirainen if (ret == -1)
76a71915c6452a4bee9a8ae89ddbdf58fa941deeTimo Sirainen break;
76a71915c6452a4bee9a8ae89ddbdf58fa941deeTimo Sirainen if (ret == -2) {
76a71915c6452a4bee9a8ae89ddbdf58fa941deeTimo Sirainen data = i_stream_get_data(filter, &size);
76a71915c6452a4bee9a8ae89ddbdf58fa941deeTimo Sirainen str_append_n(output, data, size);
76a71915c6452a4bee9a8ae89ddbdf58fa941deeTimo Sirainen i_stream_skip(filter, size);
76a71915c6452a4bee9a8ae89ddbdf58fa941deeTimo Sirainen }
76a71915c6452a4bee9a8ae89ddbdf58fa941deeTimo Sirainen }
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen /* callbacks are called only once */
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen test_assert(null_hdr_seen == (i == 0));
76a71915c6452a4bee9a8ae89ddbdf58fa941deeTimo Sirainen
76a71915c6452a4bee9a8ae89ddbdf58fa941deeTimo Sirainen data = i_stream_get_data(filter, &size);
76a71915c6452a4bee9a8ae89ddbdf58fa941deeTimo Sirainen test_assert(size <= 8192);
76a71915c6452a4bee9a8ae89ddbdf58fa941deeTimo Sirainen str_append_n(output, data, size);
76a71915c6452a4bee9a8ae89ddbdf58fa941deeTimo Sirainen
76a71915c6452a4bee9a8ae89ddbdf58fa941deeTimo Sirainen p = strstr(str_c(input), "To: ");
76a71915c6452a4bee9a8ae89ddbdf58fa941deeTimo Sirainen i_assert(p != NULL);
76a71915c6452a4bee9a8ae89ddbdf58fa941deeTimo Sirainen prefix_len = p - str_c(input);
76a71915c6452a4bee9a8ae89ddbdf58fa941deeTimo Sirainen test_assert(strncmp(str_c(input), str_c(output), prefix_len) == 0);
76a71915c6452a4bee9a8ae89ddbdf58fa941deeTimo Sirainen
76a71915c6452a4bee9a8ae89ddbdf58fa941deeTimo Sirainen p = strchr(p, '\n');
76a71915c6452a4bee9a8ae89ddbdf58fa941deeTimo Sirainen i_assert(p != NULL);
76a71915c6452a4bee9a8ae89ddbdf58fa941deeTimo Sirainen test_assert(strcmp(p+1, str_c(output) + prefix_len) == 0);
76a71915c6452a4bee9a8ae89ddbdf58fa941deeTimo Sirainen
c8e34785671d3b13f4500144a2ec7af968ce3307Timo Sirainen test_assert(i_stream_stat(filter, TRUE, &st) == 0 &&
c8e34785671d3b13f4500144a2ec7af968ce3307Timo Sirainen (uoff_t)st->st_size == filter->v_offset + size);
c8e34785671d3b13f4500144a2ec7af968ce3307Timo Sirainen
270c7cd669b1ad4b69edb366dc5f22262948bfedTimo Sirainen /* seek back and retry once with caching and different
270c7cd669b1ad4b69edb366dc5f22262948bfedTimo Sirainen buffer size */
76a71915c6452a4bee9a8ae89ddbdf58fa941deeTimo Sirainen i_stream_seek(filter, 0);
76a71915c6452a4bee9a8ae89ddbdf58fa941deeTimo Sirainen str_truncate(output, 0);
270c7cd669b1ad4b69edb366dc5f22262948bfedTimo Sirainen test_istream_set_max_buffer_size(istream, 4096);
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen null_hdr_seen = FALSE;
76a71915c6452a4bee9a8ae89ddbdf58fa941deeTimo Sirainen }
76a71915c6452a4bee9a8ae89ddbdf58fa941deeTimo Sirainen
76a71915c6452a4bee9a8ae89ddbdf58fa941deeTimo Sirainen str_free(&input);
76a71915c6452a4bee9a8ae89ddbdf58fa941deeTimo Sirainen str_free(&output);
76a71915c6452a4bee9a8ae89ddbdf58fa941deeTimo Sirainen i_stream_unref(&filter);
76a71915c6452a4bee9a8ae89ddbdf58fa941deeTimo Sirainen i_stream_unref(&istream);
76a71915c6452a4bee9a8ae89ddbdf58fa941deeTimo Sirainen
76a71915c6452a4bee9a8ae89ddbdf58fa941deeTimo Sirainen test_end();
76a71915c6452a4bee9a8ae89ddbdf58fa941deeTimo Sirainen}
76a71915c6452a4bee9a8ae89ddbdf58fa941deeTimo Sirainen
07bba7cf547c26c6f46f23bb84b6cab919b4ae0cTimo Sirainenstatic void test_istream_filter_large_buffer2(void)
07bba7cf547c26c6f46f23bb84b6cab919b4ae0cTimo Sirainen{
07bba7cf547c26c6f46f23bb84b6cab919b4ae0cTimo Sirainen static const char *wanted_headers[] = { "References" };
07bba7cf547c26c6f46f23bb84b6cab919b4ae0cTimo Sirainen string_t *input, *output;
07bba7cf547c26c6f46f23bb84b6cab919b4ae0cTimo Sirainen struct istream *istream, *filter;
07bba7cf547c26c6f46f23bb84b6cab919b4ae0cTimo Sirainen const struct stat *st;
07bba7cf547c26c6f46f23bb84b6cab919b4ae0cTimo Sirainen const unsigned char *data;
07bba7cf547c26c6f46f23bb84b6cab919b4ae0cTimo Sirainen size_t size;
07bba7cf547c26c6f46f23bb84b6cab919b4ae0cTimo Sirainen unsigned int i;
07bba7cf547c26c6f46f23bb84b6cab919b4ae0cTimo Sirainen int ret;
07bba7cf547c26c6f46f23bb84b6cab919b4ae0cTimo Sirainen
07bba7cf547c26c6f46f23bb84b6cab919b4ae0cTimo Sirainen test_begin("i_stream_create_header_filter: large buffer2");
07bba7cf547c26c6f46f23bb84b6cab919b4ae0cTimo Sirainen
07bba7cf547c26c6f46f23bb84b6cab919b4ae0cTimo Sirainen input = str_new(default_pool, 1024*128);
07bba7cf547c26c6f46f23bb84b6cab919b4ae0cTimo Sirainen output = str_new(default_pool, 1024*128);
07bba7cf547c26c6f46f23bb84b6cab919b4ae0cTimo Sirainen str_append(input, "References: ");
07bba7cf547c26c6f46f23bb84b6cab919b4ae0cTimo Sirainen add_random_text(input, 1024*64);
07bba7cf547c26c6f46f23bb84b6cab919b4ae0cTimo Sirainen str_append(input, "\r\n\r\n");
07bba7cf547c26c6f46f23bb84b6cab919b4ae0cTimo Sirainen
07bba7cf547c26c6f46f23bb84b6cab919b4ae0cTimo Sirainen istream = test_istream_create_data(str_data(input), str_len(input));
07bba7cf547c26c6f46f23bb84b6cab919b4ae0cTimo Sirainen test_istream_set_max_buffer_size(istream, 8192);
07bba7cf547c26c6f46f23bb84b6cab919b4ae0cTimo Sirainen
07bba7cf547c26c6f46f23bb84b6cab919b4ae0cTimo Sirainen filter = i_stream_create_header_filter(istream,
07bba7cf547c26c6f46f23bb84b6cab919b4ae0cTimo Sirainen HEADER_FILTER_INCLUDE | HEADER_FILTER_HIDE_BODY,
07bba7cf547c26c6f46f23bb84b6cab919b4ae0cTimo Sirainen wanted_headers, N_ELEMENTS(wanted_headers),
677b75f90d81eafe742896d6570a2f63ce501d05Josef 'Jeff' Sipek *null_header_filter_callback, NULL);
07bba7cf547c26c6f46f23bb84b6cab919b4ae0cTimo Sirainen
07bba7cf547c26c6f46f23bb84b6cab919b4ae0cTimo Sirainen for (i = 0; i < 2; i++) {
07bba7cf547c26c6f46f23bb84b6cab919b4ae0cTimo Sirainen while ((ret = i_stream_read_more(filter, &data, &size)) > 0) {
07bba7cf547c26c6f46f23bb84b6cab919b4ae0cTimo Sirainen str_append_n(output, data, size);
07bba7cf547c26c6f46f23bb84b6cab919b4ae0cTimo Sirainen i_stream_skip(filter, size);
07bba7cf547c26c6f46f23bb84b6cab919b4ae0cTimo Sirainen }
07bba7cf547c26c6f46f23bb84b6cab919b4ae0cTimo Sirainen test_assert(ret == -1);
07bba7cf547c26c6f46f23bb84b6cab919b4ae0cTimo Sirainen test_assert(filter->stream_errno == 0);
07bba7cf547c26c6f46f23bb84b6cab919b4ae0cTimo Sirainen
07bba7cf547c26c6f46f23bb84b6cab919b4ae0cTimo Sirainen test_assert(strcmp(str_c(input), str_c(output)) == 0);
07bba7cf547c26c6f46f23bb84b6cab919b4ae0cTimo Sirainen test_assert(i_stream_stat(filter, TRUE, &st) == 0 &&
07bba7cf547c26c6f46f23bb84b6cab919b4ae0cTimo Sirainen (uoff_t)st->st_size == filter->v_offset + size);
07bba7cf547c26c6f46f23bb84b6cab919b4ae0cTimo Sirainen
07bba7cf547c26c6f46f23bb84b6cab919b4ae0cTimo Sirainen /* seek back and retry once with caching and different
07bba7cf547c26c6f46f23bb84b6cab919b4ae0cTimo Sirainen buffer size */
07bba7cf547c26c6f46f23bb84b6cab919b4ae0cTimo Sirainen i_stream_seek(filter, 0);
07bba7cf547c26c6f46f23bb84b6cab919b4ae0cTimo Sirainen str_truncate(output, 0);
07bba7cf547c26c6f46f23bb84b6cab919b4ae0cTimo Sirainen test_istream_set_max_buffer_size(istream, 4096);
07bba7cf547c26c6f46f23bb84b6cab919b4ae0cTimo Sirainen }
07bba7cf547c26c6f46f23bb84b6cab919b4ae0cTimo Sirainen
07bba7cf547c26c6f46f23bb84b6cab919b4ae0cTimo Sirainen str_free(&input);
07bba7cf547c26c6f46f23bb84b6cab919b4ae0cTimo Sirainen str_free(&output);
07bba7cf547c26c6f46f23bb84b6cab919b4ae0cTimo Sirainen i_stream_unref(&filter);
07bba7cf547c26c6f46f23bb84b6cab919b4ae0cTimo Sirainen i_stream_unref(&istream);
07bba7cf547c26c6f46f23bb84b6cab919b4ae0cTimo Sirainen
07bba7cf547c26c6f46f23bb84b6cab919b4ae0cTimo Sirainen test_end();
07bba7cf547c26c6f46f23bb84b6cab919b4ae0cTimo Sirainen}
07bba7cf547c26c6f46f23bb84b6cab919b4ae0cTimo Sirainen
88d100753bd4b26f038093d3794c2dc50875443dTimo Sirainenstatic void
88d100753bd4b26f038093d3794c2dc50875443dTimo Sirainenfilter3_callback(struct header_filter_istream *input ATTR_UNUSED,
88d100753bd4b26f038093d3794c2dc50875443dTimo Sirainen struct message_header_line *hdr,
88d100753bd4b26f038093d3794c2dc50875443dTimo Sirainen bool *matched ATTR_UNUSED, string_t *dest)
88d100753bd4b26f038093d3794c2dc50875443dTimo Sirainen{
88d100753bd4b26f038093d3794c2dc50875443dTimo Sirainen if (hdr != NULL)
88d100753bd4b26f038093d3794c2dc50875443dTimo Sirainen message_header_line_write(dest, hdr);
88d100753bd4b26f038093d3794c2dc50875443dTimo Sirainen}
88d100753bd4b26f038093d3794c2dc50875443dTimo Sirainen
88d100753bd4b26f038093d3794c2dc50875443dTimo Sirainenstatic void test_istream_callbacks(void)
88d100753bd4b26f038093d3794c2dc50875443dTimo Sirainen{
88d100753bd4b26f038093d3794c2dc50875443dTimo Sirainen string_t *input, *output;
c8e34785671d3b13f4500144a2ec7af968ce3307Timo Sirainen const struct stat *st;
88d100753bd4b26f038093d3794c2dc50875443dTimo Sirainen struct istream *istream, *filter;
88d100753bd4b26f038093d3794c2dc50875443dTimo Sirainen unsigned int i;
88d100753bd4b26f038093d3794c2dc50875443dTimo Sirainen
6e81d67a4e8985d35034eab791e270ffc01800b8Timo Sirainen test_begin("i_stream_create_header_filter: callbacks");
88d100753bd4b26f038093d3794c2dc50875443dTimo Sirainen
88d100753bd4b26f038093d3794c2dc50875443dTimo Sirainen input = str_new(default_pool, 1024*128);
88d100753bd4b26f038093d3794c2dc50875443dTimo Sirainen output = str_new(default_pool, 1024*128);
88d100753bd4b26f038093d3794c2dc50875443dTimo Sirainen str_append(input, "From: first line\n ");
88d100753bd4b26f038093d3794c2dc50875443dTimo Sirainen add_random_text(input, 1024*31);
88d100753bd4b26f038093d3794c2dc50875443dTimo Sirainen str_append(input, "\nTo: first line\n\tsecond line\n\t");
88d100753bd4b26f038093d3794c2dc50875443dTimo Sirainen add_random_text(input, 1024*32);
88d100753bd4b26f038093d3794c2dc50875443dTimo Sirainen str_append(input, "\n last line\nSubject: ");
88d100753bd4b26f038093d3794c2dc50875443dTimo Sirainen add_random_text(input, 1024*34);
88d100753bd4b26f038093d3794c2dc50875443dTimo Sirainen str_append(input, "\n");
88d100753bd4b26f038093d3794c2dc50875443dTimo Sirainen
88d100753bd4b26f038093d3794c2dc50875443dTimo Sirainen istream = test_istream_create_data(str_data(input), str_len(input));
88d100753bd4b26f038093d3794c2dc50875443dTimo Sirainen test_istream_set_max_buffer_size(istream, 8192);
88d100753bd4b26f038093d3794c2dc50875443dTimo Sirainen
88d100753bd4b26f038093d3794c2dc50875443dTimo Sirainen filter = i_stream_create_header_filter(istream,
88d100753bd4b26f038093d3794c2dc50875443dTimo Sirainen HEADER_FILTER_EXCLUDE |
88d100753bd4b26f038093d3794c2dc50875443dTimo Sirainen HEADER_FILTER_NO_CR,
88d100753bd4b26f038093d3794c2dc50875443dTimo Sirainen NULL, 0,
88d100753bd4b26f038093d3794c2dc50875443dTimo Sirainen filter3_callback,
88d100753bd4b26f038093d3794c2dc50875443dTimo Sirainen output);
88d100753bd4b26f038093d3794c2dc50875443dTimo Sirainen
88d100753bd4b26f038093d3794c2dc50875443dTimo Sirainen /* callback should be called exactly once for all the header input */
88d100753bd4b26f038093d3794c2dc50875443dTimo Sirainen for (i = 0; i < 2; i++) {
88d100753bd4b26f038093d3794c2dc50875443dTimo Sirainen while (i_stream_read(filter) != -1)
88d100753bd4b26f038093d3794c2dc50875443dTimo Sirainen i_stream_skip(filter, i_stream_get_data_size(filter));
88d100753bd4b26f038093d3794c2dc50875443dTimo Sirainen }
88d100753bd4b26f038093d3794c2dc50875443dTimo Sirainen
c8e34785671d3b13f4500144a2ec7af968ce3307Timo Sirainen test_assert(i_stream_stat(filter, TRUE, &st) == 0 &&
c8e34785671d3b13f4500144a2ec7af968ce3307Timo Sirainen (uoff_t)st->st_size == str_len(output));
88d100753bd4b26f038093d3794c2dc50875443dTimo Sirainen test_assert(strcmp(str_c(output), str_c(input)) == 0);
88d100753bd4b26f038093d3794c2dc50875443dTimo Sirainen str_free(&input);
88d100753bd4b26f038093d3794c2dc50875443dTimo Sirainen str_free(&output);
88d100753bd4b26f038093d3794c2dc50875443dTimo Sirainen i_stream_unref(&filter);
88d100753bd4b26f038093d3794c2dc50875443dTimo Sirainen i_stream_unref(&istream);
88d100753bd4b26f038093d3794c2dc50875443dTimo Sirainen
88d100753bd4b26f038093d3794c2dc50875443dTimo Sirainen test_end();
88d100753bd4b26f038093d3794c2dc50875443dTimo Sirainen}
88d100753bd4b26f038093d3794c2dc50875443dTimo Sirainen
82705acc82d625a60146b72b9296146dd8312261Timo Sirainenstatic void ATTR_NULL(3)
82705acc82d625a60146b72b9296146dd8312261Timo Sirainenedit_callback(struct header_filter_istream *input,
82705acc82d625a60146b72b9296146dd8312261Timo Sirainen struct message_header_line *hdr,
82705acc82d625a60146b72b9296146dd8312261Timo Sirainen bool *matched, void *context ATTR_UNUSED)
82705acc82d625a60146b72b9296146dd8312261Timo Sirainen{
bf5682ed5399fce13b2053e20098e2de19751c59Timo Sirainen if (hdr == NULL)
bf5682ed5399fce13b2053e20098e2de19751c59Timo Sirainen return;
bf5682ed5399fce13b2053e20098e2de19751c59Timo Sirainen if (hdr->eoh) {
bf5682ed5399fce13b2053e20098e2de19751c59Timo Sirainen /* add a new header */
bf5682ed5399fce13b2053e20098e2de19751c59Timo Sirainen const char *new_hdr = "Added: header\n\n";
bf5682ed5399fce13b2053e20098e2de19751c59Timo Sirainen i_stream_header_filter_add(input, new_hdr, strlen(new_hdr));
44ef49403ac7bddac84a1e322d170ed53cd37c95Timo Sirainen *matched = TRUE;
bf5682ed5399fce13b2053e20098e2de19751c59Timo Sirainen } else if (strcasecmp(hdr->name, "To") == 0) {
82705acc82d625a60146b72b9296146dd8312261Timo Sirainen /* modify To header */
82705acc82d625a60146b72b9296146dd8312261Timo Sirainen const char *new_to = "To: 123\n";
82705acc82d625a60146b72b9296146dd8312261Timo Sirainen *matched = TRUE;
82705acc82d625a60146b72b9296146dd8312261Timo Sirainen i_stream_header_filter_add(input, new_to, strlen(new_to));
82705acc82d625a60146b72b9296146dd8312261Timo Sirainen }
82705acc82d625a60146b72b9296146dd8312261Timo Sirainen}
82705acc82d625a60146b72b9296146dd8312261Timo Sirainen
82705acc82d625a60146b72b9296146dd8312261Timo Sirainenstatic void test_istream_edit(void)
82705acc82d625a60146b72b9296146dd8312261Timo Sirainen{
82705acc82d625a60146b72b9296146dd8312261Timo Sirainen const char *input = "From: foo\nTo: bar\n\nhello world\n";
bf5682ed5399fce13b2053e20098e2de19751c59Timo Sirainen const char *output = "From: foo\nTo: 123\nAdded: header\n\nhello world\n";
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen struct istream *istream;
82705acc82d625a60146b72b9296146dd8312261Timo Sirainen
6e81d67a4e8985d35034eab791e270ffc01800b8Timo Sirainen test_begin("i_stream_create_header_filter: edit headers");
82705acc82d625a60146b72b9296146dd8312261Timo Sirainen istream = test_istream_create(input);
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen test_istream_run(istream, strlen(input), output,
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen HEADER_FILTER_EXCLUDE |
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen HEADER_FILTER_NO_CR,
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen edit_callback);
82705acc82d625a60146b72b9296146dd8312261Timo Sirainen i_stream_unref(&istream);
82705acc82d625a60146b72b9296146dd8312261Timo Sirainen
82705acc82d625a60146b72b9296146dd8312261Timo Sirainen test_end();
82705acc82d625a60146b72b9296146dd8312261Timo Sirainen}
82705acc82d625a60146b72b9296146dd8312261Timo Sirainen
ef3ebb56989cb9b1b80edd133a091338e4206836Timo Sirainenstatic void test_istream_end_body_with_lf(void)
ef3ebb56989cb9b1b80edd133a091338e4206836Timo Sirainen{
ef3ebb56989cb9b1b80edd133a091338e4206836Timo Sirainen const char *input = "From: foo\n\nhello world";
ef3ebb56989cb9b1b80edd133a091338e4206836Timo Sirainen const char *output = "From: foo\n\nhello world\n";
c8e34785671d3b13f4500144a2ec7af968ce3307Timo Sirainen const struct stat *st;
ef3ebb56989cb9b1b80edd133a091338e4206836Timo Sirainen struct istream *istream, *filter;
2ac5f36aa7c2e7a07ba8815d43a6d7483f62e74cTimo Sirainen unsigned int i;
2ac5f36aa7c2e7a07ba8815d43a6d7483f62e74cTimo Sirainen size_t input_len = strlen(input);
2ac5f36aa7c2e7a07ba8815d43a6d7483f62e74cTimo Sirainen size_t output_len = strlen(output);
ef3ebb56989cb9b1b80edd133a091338e4206836Timo Sirainen const unsigned char *data;
ef3ebb56989cb9b1b80edd133a091338e4206836Timo Sirainen string_t *str = t_str_new(64);
ef3ebb56989cb9b1b80edd133a091338e4206836Timo Sirainen size_t size;
ef3ebb56989cb9b1b80edd133a091338e4206836Timo Sirainen
6e81d67a4e8985d35034eab791e270ffc01800b8Timo Sirainen test_begin("i_stream_create_header_filter: end_body_with_lf");
ef3ebb56989cb9b1b80edd133a091338e4206836Timo Sirainen istream = test_istream_create(input);
ef3ebb56989cb9b1b80edd133a091338e4206836Timo Sirainen filter = i_stream_create_header_filter(istream,
ef3ebb56989cb9b1b80edd133a091338e4206836Timo Sirainen HEADER_FILTER_EXCLUDE |
ef3ebb56989cb9b1b80edd133a091338e4206836Timo Sirainen HEADER_FILTER_NO_CR |
ef3ebb56989cb9b1b80edd133a091338e4206836Timo Sirainen HEADER_FILTER_END_BODY_WITH_LF,
2719970c2c246f976178da179deeb64eecaec5baTimo Sirainen NULL, 0,
27a44fcfd8d19bffe0f267f20a2b5d3fe7600fddTimo Sirainen *null_header_filter_callback,
677b75f90d81eafe742896d6570a2f63ce501d05Josef 'Jeff' Sipek NULL);
ef3ebb56989cb9b1b80edd133a091338e4206836Timo Sirainen
ef3ebb56989cb9b1b80edd133a091338e4206836Timo Sirainen for (i = 1; i < input_len; i++) {
ef3ebb56989cb9b1b80edd133a091338e4206836Timo Sirainen test_istream_set_size(istream, i);
ef3ebb56989cb9b1b80edd133a091338e4206836Timo Sirainen test_assert(i_stream_read(filter) >= 0);
ef3ebb56989cb9b1b80edd133a091338e4206836Timo Sirainen }
ef3ebb56989cb9b1b80edd133a091338e4206836Timo Sirainen test_istream_set_size(istream, input_len);
ef3ebb56989cb9b1b80edd133a091338e4206836Timo Sirainen test_assert(i_stream_read(filter) > 0);
ef3ebb56989cb9b1b80edd133a091338e4206836Timo Sirainen test_assert(i_stream_read(filter) > 0);
ef3ebb56989cb9b1b80edd133a091338e4206836Timo Sirainen test_assert(i_stream_read(filter) == -1);
ef3ebb56989cb9b1b80edd133a091338e4206836Timo Sirainen
ef3ebb56989cb9b1b80edd133a091338e4206836Timo Sirainen data = i_stream_get_data(filter, &size);
ef3ebb56989cb9b1b80edd133a091338e4206836Timo Sirainen test_assert(size == output_len && memcmp(data, output, size) == 0);
c8e34785671d3b13f4500144a2ec7af968ce3307Timo Sirainen test_assert(i_stream_stat(filter, TRUE, &st) == 0 &&
c8e34785671d3b13f4500144a2ec7af968ce3307Timo Sirainen (uoff_t)st->st_size == filter->v_offset + size);
ef3ebb56989cb9b1b80edd133a091338e4206836Timo Sirainen
ef3ebb56989cb9b1b80edd133a091338e4206836Timo Sirainen i_stream_skip(filter, size);
ef3ebb56989cb9b1b80edd133a091338e4206836Timo Sirainen i_stream_seek(filter, 0);
ef3ebb56989cb9b1b80edd133a091338e4206836Timo Sirainen for (i = 1; i < input_len; i++) {
ef3ebb56989cb9b1b80edd133a091338e4206836Timo Sirainen test_istream_set_size(istream, i);
ef3ebb56989cb9b1b80edd133a091338e4206836Timo Sirainen test_assert(i_stream_read(filter) >= 0);
ef3ebb56989cb9b1b80edd133a091338e4206836Timo Sirainen
ef3ebb56989cb9b1b80edd133a091338e4206836Timo Sirainen data = i_stream_get_data(filter, &size);
d4488f314d0c799c5f5b8a7890e17eef868f7a2cMartti Rannanjärvi if (size > 0)
d4488f314d0c799c5f5b8a7890e17eef868f7a2cMartti Rannanjärvi str_append_n(str, data, size);
ef3ebb56989cb9b1b80edd133a091338e4206836Timo Sirainen i_stream_skip(filter, size);
ef3ebb56989cb9b1b80edd133a091338e4206836Timo Sirainen }
ef3ebb56989cb9b1b80edd133a091338e4206836Timo Sirainen test_istream_set_size(istream, input_len);
ef3ebb56989cb9b1b80edd133a091338e4206836Timo Sirainen test_assert(i_stream_read(filter) == 1);
ef3ebb56989cb9b1b80edd133a091338e4206836Timo Sirainen test_assert(i_stream_read(filter) == 1);
ef3ebb56989cb9b1b80edd133a091338e4206836Timo Sirainen test_assert(i_stream_read(filter) == -1);
ef3ebb56989cb9b1b80edd133a091338e4206836Timo Sirainen
ef3ebb56989cb9b1b80edd133a091338e4206836Timo Sirainen data = i_stream_get_data(filter, &size);
ef3ebb56989cb9b1b80edd133a091338e4206836Timo Sirainen str_append_n(str, data, size);
ef3ebb56989cb9b1b80edd133a091338e4206836Timo Sirainen test_assert(strcmp(str_c(str), output) == 0);
ef3ebb56989cb9b1b80edd133a091338e4206836Timo Sirainen
ef3ebb56989cb9b1b80edd133a091338e4206836Timo Sirainen i_stream_unref(&filter);
ef3ebb56989cb9b1b80edd133a091338e4206836Timo Sirainen i_stream_unref(&istream);
ef3ebb56989cb9b1b80edd133a091338e4206836Timo Sirainen
ef3ebb56989cb9b1b80edd133a091338e4206836Timo Sirainen test_end();
ef3ebb56989cb9b1b80edd133a091338e4206836Timo Sirainen}
ef3ebb56989cb9b1b80edd133a091338e4206836Timo Sirainen
10d2dbb8343d9f7a294519224e5e08e1c13e7453Timo Sirainenstatic void test_istream_add_missing_eoh(void)
10d2dbb8343d9f7a294519224e5e08e1c13e7453Timo Sirainen{
b7324e421e2132cbbf753e6fdbe675bbaecdf929Timo Sirainen static const struct {
10d2dbb8343d9f7a294519224e5e08e1c13e7453Timo Sirainen const char *input;
10d2dbb8343d9f7a294519224e5e08e1c13e7453Timo Sirainen const char *output;
10d2dbb8343d9f7a294519224e5e08e1c13e7453Timo Sirainen unsigned int extra;
10d2dbb8343d9f7a294519224e5e08e1c13e7453Timo Sirainen } tests[] = {
5695ec03a0cc4836896e46a01bb9336782aee326Timo Sirainen { "", "\n", 0 },
10d2dbb8343d9f7a294519224e5e08e1c13e7453Timo Sirainen { "From: foo", "From: foo\n\n", 1 },
10d2dbb8343d9f7a294519224e5e08e1c13e7453Timo Sirainen { "From: foo\n", "From: foo\n\n", 1 },
10d2dbb8343d9f7a294519224e5e08e1c13e7453Timo Sirainen { "From: foo\n\n", "From: foo\n\n", 1 },
10d2dbb8343d9f7a294519224e5e08e1c13e7453Timo Sirainen { "From: foo\n\nbar", "From: foo\n\nbar", 0 },
10d2dbb8343d9f7a294519224e5e08e1c13e7453Timo Sirainen { "From: foo\r\n", "From: foo\r\n\r\n", 1 },
10d2dbb8343d9f7a294519224e5e08e1c13e7453Timo Sirainen { "From: foo\r\n\r\n", "From: foo\r\n\r\n", 0 },
10d2dbb8343d9f7a294519224e5e08e1c13e7453Timo Sirainen { "From: foo\r\n\r\nbar", "From: foo\r\n\r\nbar", 0 }
10d2dbb8343d9f7a294519224e5e08e1c13e7453Timo Sirainen };
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen struct istream *istream;
10d2dbb8343d9f7a294519224e5e08e1c13e7453Timo Sirainen unsigned int i;
10d2dbb8343d9f7a294519224e5e08e1c13e7453Timo Sirainen
6e81d67a4e8985d35034eab791e270ffc01800b8Timo Sirainen test_begin("i_stream_create_header_filter: add missing EOH");
10d2dbb8343d9f7a294519224e5e08e1c13e7453Timo Sirainen for (i = 0; i < N_ELEMENTS(tests); i++) {
10d2dbb8343d9f7a294519224e5e08e1c13e7453Timo Sirainen istream = test_istream_create(tests[i].input);
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen test_istream_run(istream,
10d2dbb8343d9f7a294519224e5e08e1c13e7453Timo Sirainen strlen(tests[i].input) + tests[i].extra,
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen tests[i].output,
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen HEADER_FILTER_EXCLUDE |
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen HEADER_FILTER_CRLF_PRESERVE |
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen HEADER_FILTER_ADD_MISSING_EOH,
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen *null_header_filter_callback);
10d2dbb8343d9f7a294519224e5e08e1c13e7453Timo Sirainen i_stream_unref(&istream);
10d2dbb8343d9f7a294519224e5e08e1c13e7453Timo Sirainen }
10d2dbb8343d9f7a294519224e5e08e1c13e7453Timo Sirainen test_end();
10d2dbb8343d9f7a294519224e5e08e1c13e7453Timo Sirainen}
10d2dbb8343d9f7a294519224e5e08e1c13e7453Timo Sirainen
201ce62e1dc315e5dd5e59c24660ed0946343bbbTimo Sirainenstatic void test_istream_add_missing_eoh_and_edit(void)
201ce62e1dc315e5dd5e59c24660ed0946343bbbTimo Sirainen{
201ce62e1dc315e5dd5e59c24660ed0946343bbbTimo Sirainen const char *input = "From: foo\nTo: bar\n";
201ce62e1dc315e5dd5e59c24660ed0946343bbbTimo Sirainen const char *output = "From: foo\nTo: 123\nAdded: header\n\n";
201ce62e1dc315e5dd5e59c24660ed0946343bbbTimo Sirainen struct istream *istream;
201ce62e1dc315e5dd5e59c24660ed0946343bbbTimo Sirainen
201ce62e1dc315e5dd5e59c24660ed0946343bbbTimo Sirainen test_begin("i_stream_create_header_filter: add missing EOH and edit headers");
201ce62e1dc315e5dd5e59c24660ed0946343bbbTimo Sirainen istream = test_istream_create(input);
201ce62e1dc315e5dd5e59c24660ed0946343bbbTimo Sirainen test_istream_run(istream, strlen(input), output,
201ce62e1dc315e5dd5e59c24660ed0946343bbbTimo Sirainen HEADER_FILTER_EXCLUDE |
201ce62e1dc315e5dd5e59c24660ed0946343bbbTimo Sirainen HEADER_FILTER_ADD_MISSING_EOH |
201ce62e1dc315e5dd5e59c24660ed0946343bbbTimo Sirainen HEADER_FILTER_NO_CR,
201ce62e1dc315e5dd5e59c24660ed0946343bbbTimo Sirainen edit_callback);
201ce62e1dc315e5dd5e59c24660ed0946343bbbTimo Sirainen i_stream_unref(&istream);
201ce62e1dc315e5dd5e59c24660ed0946343bbbTimo Sirainen
201ce62e1dc315e5dd5e59c24660ed0946343bbbTimo Sirainen test_end();
201ce62e1dc315e5dd5e59c24660ed0946343bbbTimo Sirainen}
201ce62e1dc315e5dd5e59c24660ed0946343bbbTimo Sirainen
32e3da4a505b3b258d44abdf4366fbfc95680027Timo Sirainenstatic void test_istream_hide_body(void)
32e3da4a505b3b258d44abdf4366fbfc95680027Timo Sirainen{
b7324e421e2132cbbf753e6fdbe675bbaecdf929Timo Sirainen static const struct {
32e3da4a505b3b258d44abdf4366fbfc95680027Timo Sirainen const char *input;
32e3da4a505b3b258d44abdf4366fbfc95680027Timo Sirainen const char *output;
32e3da4a505b3b258d44abdf4366fbfc95680027Timo Sirainen int extra;
32e3da4a505b3b258d44abdf4366fbfc95680027Timo Sirainen } tests[] = {
32e3da4a505b3b258d44abdf4366fbfc95680027Timo Sirainen { "From: foo", "From: foo", 0 },
32e3da4a505b3b258d44abdf4366fbfc95680027Timo Sirainen { "From: foo\n", "From: foo\n", 0 },
32e3da4a505b3b258d44abdf4366fbfc95680027Timo Sirainen { "From: foo\n\n", "From: foo\n\n", 1 },
32e3da4a505b3b258d44abdf4366fbfc95680027Timo Sirainen { "From: foo\n\nbar", "From: foo\n\n", -2 },
32e3da4a505b3b258d44abdf4366fbfc95680027Timo Sirainen { "From: foo\r\n", "From: foo\r\n", 0 },
32e3da4a505b3b258d44abdf4366fbfc95680027Timo Sirainen { "From: foo\r\n\r\n", "From: foo\r\n\r\n", 0 },
32e3da4a505b3b258d44abdf4366fbfc95680027Timo Sirainen { "From: foo\r\n\r\nbar", "From: foo\r\n\r\n", -3 }
32e3da4a505b3b258d44abdf4366fbfc95680027Timo Sirainen };
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen struct istream *istream;
32e3da4a505b3b258d44abdf4366fbfc95680027Timo Sirainen unsigned int i;
32e3da4a505b3b258d44abdf4366fbfc95680027Timo Sirainen
6e81d67a4e8985d35034eab791e270ffc01800b8Timo Sirainen test_begin("i_stream_create_header_filter: hide body");
32e3da4a505b3b258d44abdf4366fbfc95680027Timo Sirainen for (i = 0; i < N_ELEMENTS(tests); i++) {
32e3da4a505b3b258d44abdf4366fbfc95680027Timo Sirainen istream = test_istream_create(tests[i].input);
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen test_istream_run(istream,
fced91d6314b7c934650b6ee2c540abc520efd74Timo Sirainen (int)strlen(tests[i].input) + tests[i].extra,
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen tests[i].output,
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen HEADER_FILTER_EXCLUDE |
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen HEADER_FILTER_CRLF_PRESERVE |
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen HEADER_FILTER_HIDE_BODY,
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen *null_header_filter_callback);
32e3da4a505b3b258d44abdf4366fbfc95680027Timo Sirainen i_stream_unref(&istream);
32e3da4a505b3b258d44abdf4366fbfc95680027Timo Sirainen }
32e3da4a505b3b258d44abdf4366fbfc95680027Timo Sirainen test_end();
32e3da4a505b3b258d44abdf4366fbfc95680027Timo Sirainen}
32e3da4a505b3b258d44abdf4366fbfc95680027Timo Sirainen
adb90447f6bf7b11b5fca7e87a3f256622fdef9fTimo Sirainenstatic void ATTR_NULL(3)
adb90447f6bf7b11b5fca7e87a3f256622fdef9fTimo Sirainenstrip_eoh_callback(struct header_filter_istream *input ATTR_UNUSED,
adb90447f6bf7b11b5fca7e87a3f256622fdef9fTimo Sirainen struct message_header_line *hdr,
adb90447f6bf7b11b5fca7e87a3f256622fdef9fTimo Sirainen bool *matched, void *context ATTR_UNUSED)
adb90447f6bf7b11b5fca7e87a3f256622fdef9fTimo Sirainen{
adb90447f6bf7b11b5fca7e87a3f256622fdef9fTimo Sirainen if (hdr != NULL && hdr->eoh)
44ef49403ac7bddac84a1e322d170ed53cd37c95Timo Sirainen *matched = TRUE;
adb90447f6bf7b11b5fca7e87a3f256622fdef9fTimo Sirainen}
adb90447f6bf7b11b5fca7e87a3f256622fdef9fTimo Sirainen
adb90447f6bf7b11b5fca7e87a3f256622fdef9fTimo Sirainenstatic void test_istream_strip_eoh(void)
adb90447f6bf7b11b5fca7e87a3f256622fdef9fTimo Sirainen{
adb90447f6bf7b11b5fca7e87a3f256622fdef9fTimo Sirainen const char *input = "From: foo\nTo: bar\n\nhello world\n";
adb90447f6bf7b11b5fca7e87a3f256622fdef9fTimo Sirainen const char *output = "From: foo\nTo: bar\nhello world\n";
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen struct istream *istream;
adb90447f6bf7b11b5fca7e87a3f256622fdef9fTimo Sirainen
6e81d67a4e8985d35034eab791e270ffc01800b8Timo Sirainen test_begin("i_stream_create_header_filter: strip_eoh");
adb90447f6bf7b11b5fca7e87a3f256622fdef9fTimo Sirainen istream = test_istream_create(input);
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen test_istream_run(istream, strlen(input), output,
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen HEADER_FILTER_EXCLUDE | HEADER_FILTER_NO_CR,
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen strip_eoh_callback);
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen i_stream_unref(&istream);
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen test_end();
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen}
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainenstatic void ATTR_NULL(3)
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainenmissing_eoh_callback(struct header_filter_istream *input ATTR_UNUSED,
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen struct message_header_line *hdr,
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen bool *matched ATTR_UNUSED, void *context ATTR_UNUSED)
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen{
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen if (hdr == NULL) {
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen const char *new_hdr = "Subject: added\n\n";
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen i_stream_header_filter_add(input, new_hdr, strlen(new_hdr));
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen }
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen}
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainenstatic void test_istream_missing_eoh_callback(void)
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen{
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen const char *input = "From: foo\nTo: bar\n";
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen const char *output = "From: foo\nTo: bar\nSubject: added\n\n";
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen struct istream *istream;
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen test_begin("i_stream_create_header_filter: add headers when EOH is missing");
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen istream = test_istream_create(input);
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen test_istream_run(istream, strlen(input) + 1, output,
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen HEADER_FILTER_EXCLUDE | HEADER_FILTER_NO_CR,
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen missing_eoh_callback);
adb90447f6bf7b11b5fca7e87a3f256622fdef9fTimo Sirainen i_stream_unref(&istream);
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen test_end();
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen}
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainenstatic void test_istream_empty_missing_eoh_callback(void)
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen{
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen const char *input = "";
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen const char *output = "Subject: added\n\n";
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen struct istream *istream;
adb90447f6bf7b11b5fca7e87a3f256622fdef9fTimo Sirainen
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen test_begin("i_stream_create_header_filter: add headers when mail is empty");
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen istream = test_istream_create(input);
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen test_istream_run(istream, strlen(input)+1, output,
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen HEADER_FILTER_EXCLUDE | HEADER_FILTER_NO_CR,
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen missing_eoh_callback);
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen i_stream_unref(&istream);
adb90447f6bf7b11b5fca7e87a3f256622fdef9fTimo Sirainen test_end();
adb90447f6bf7b11b5fca7e87a3f256622fdef9fTimo Sirainen}
adb90447f6bf7b11b5fca7e87a3f256622fdef9fTimo Sirainen
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainenint main(void)
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen{
baf3e87e186453fda13bd21f7cbcb2efc8492e8bTimo Sirainen static void (*const test_functions[])(void) = {
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen test_istream_filter,
76a71915c6452a4bee9a8ae89ddbdf58fa941deeTimo Sirainen test_istream_filter_large_buffer,
07bba7cf547c26c6f46f23bb84b6cab919b4ae0cTimo Sirainen test_istream_filter_large_buffer2,
88d100753bd4b26f038093d3794c2dc50875443dTimo Sirainen test_istream_callbacks,
82705acc82d625a60146b72b9296146dd8312261Timo Sirainen test_istream_edit,
10d2dbb8343d9f7a294519224e5e08e1c13e7453Timo Sirainen test_istream_add_missing_eoh,
201ce62e1dc315e5dd5e59c24660ed0946343bbbTimo Sirainen test_istream_add_missing_eoh_and_edit,
ef3ebb56989cb9b1b80edd133a091338e4206836Timo Sirainen test_istream_end_body_with_lf,
32e3da4a505b3b258d44abdf4366fbfc95680027Timo Sirainen test_istream_hide_body,
adb90447f6bf7b11b5fca7e87a3f256622fdef9fTimo Sirainen test_istream_strip_eoh,
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen test_istream_missing_eoh_callback,
71ecc97593a25c2444316b74e5882e6ce0a82c0cTimo Sirainen test_istream_empty_missing_eoh_callback,
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen NULL
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen };
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen return test_run(test_functions);
39025a2dabfcfaeee3790988b9ea00d19887a3d3Timo Sirainen}