test-istream-header-filter.c revision 32e3da4a505b3b258d44abdf4366fbfc95680027
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* Copyright (c) 2007-2016 Dovecot authors, see the included COPYING file */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "lib.h"
16f816d3f3c32ae3351834253f52ddd0212bcbf3Timo Sirainen#include "str.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "istream.h"
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen#include "message-header-parser.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "istream-header-filter.h"
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen#include "test-common.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic void
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainentest_istream_run(struct istream *test_istream, struct istream *filter,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen unsigned int input_len, const char *output)
da5d50534cfca45d0aaaf0bdac17b287b4588809Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen unsigned int i, output_len = strlen(output);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const struct stat *st;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const unsigned char *data;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen size_t size;
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen for (i = 1; i < input_len; i++) {
e4b09b008ab544eb8994beecbfffefa21d855e43Timo Sirainen test_istream_set_size(test_istream, i);
4b231ca0bbe3b536acbd350101e183441ce0247aTimo Sirainen test_assert(i_stream_read(filter) >= 0);
4b231ca0bbe3b536acbd350101e183441ce0247aTimo Sirainen }
e4b09b008ab544eb8994beecbfffefa21d855e43Timo Sirainen test_istream_set_size(test_istream, input_len);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen test_assert(i_stream_read(filter) > 0);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen test_assert(i_stream_read(filter) == -1);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen data = i_stream_get_data(filter, &size);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen test_assert(size == output_len && memcmp(data, output, size) == 0);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* run again to make sure it's still correct the second time */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_stream_skip(filter, size);
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen i_stream_seek(filter, 0);
367c05967091a2cbfce59b7f274f55b1a0f9e8c9Timo Sirainen while (i_stream_read(filter) > 0) ;
287ba82a8da3eaa473b5735d4eeac2fb4c5d8117Timo Sirainen data = i_stream_get_data(filter, &size);
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen test_assert(size == output_len && memcmp(data, output, size) == 0);
287ba82a8da3eaa473b5735d4eeac2fb4c5d8117Timo Sirainen test_assert(i_stream_stat(filter, TRUE, &st) == 0 &&
287ba82a8da3eaa473b5735d4eeac2fb4c5d8117Timo Sirainen (uoff_t)st->st_size == size);
287ba82a8da3eaa473b5735d4eeac2fb4c5d8117Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic void ATTR_NULL(3)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenfilter_callback(struct header_filter_istream *input ATTR_UNUSED,
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen struct message_header_line *hdr,
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen bool *matched, void *context ATTR_UNUSED)
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen{
41e1c7380edda701719d8ce1fb4d465d2ec4c84dTimo Sirainen if (hdr != NULL && (hdr->name_offset == 0 ||
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen strcmp(hdr->name, "X-Drop") == 0)) {
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen /* drop 1) first header, 2) X-Drop header */
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen *matched = TRUE;
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic void test_istream_filter(void)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen static const char *exclude_headers[] = { "Subject", "To" };
ee246b46953e4b94b2f22e093373674fa9155500Timo Sirainen const char *input = "From: foo\nFrom: abc\nTo: bar\nSubject: plop\nX-Drop: 1\n\nhello world\n";
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen const char *output = "From: abc\n\nhello world\n";
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen struct istream *istream, *filter, *filter2;
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen unsigned int i, input_len = strlen(input);
41e1c7380edda701719d8ce1fb4d465d2ec4c84dTimo Sirainen unsigned int output_len = strlen(output);
ee246b46953e4b94b2f22e093373674fa9155500Timo Sirainen const unsigned char *data;
287ba82a8da3eaa473b5735d4eeac2fb4c5d8117Timo Sirainen const struct stat *st;
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen size_t size;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen test_begin("i_stream_create_header_filter(exclude)");
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen istream = test_istream_create(input);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen filter = i_stream_create_header_filter(istream,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen HEADER_FILTER_EXCLUDE |
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen HEADER_FILTER_NO_CR,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen exclude_headers,
20a802016205bbcafc90f164f769ea801f88d014Timo Sirainen N_ELEMENTS(exclude_headers),
20a802016205bbcafc90f164f769ea801f88d014Timo Sirainen filter_callback, (void *)NULL);
20a802016205bbcafc90f164f769ea801f88d014Timo Sirainen filter2 = i_stream_create_header_filter(filter,
20a802016205bbcafc90f164f769ea801f88d014Timo Sirainen HEADER_FILTER_EXCLUDE |
20a802016205bbcafc90f164f769ea801f88d014Timo Sirainen HEADER_FILTER_NO_CR,
20a802016205bbcafc90f164f769ea801f88d014Timo Sirainen exclude_headers,
20a802016205bbcafc90f164f769ea801f88d014Timo Sirainen N_ELEMENTS(exclude_headers),
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen *null_header_filter_callback,
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen (void *)NULL);
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen i_stream_unref(&filter);
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen filter = filter2;
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen for (i = 1; i < input_len; i++) {
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen test_istream_set_size(istream, i);
287ba82a8da3eaa473b5735d4eeac2fb4c5d8117Timo Sirainen test_assert(i_stream_read(filter) >= 0);
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen }
287ba82a8da3eaa473b5735d4eeac2fb4c5d8117Timo Sirainen test_istream_set_size(istream, input_len);
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen test_assert(i_stream_read(filter) > 0);
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen test_assert(i_stream_read(filter) == -1);
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen data = i_stream_get_data(filter, &size);
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen test_assert(size == output_len && memcmp(data, output, size) == 0);
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen
1175f27441385a7011629f295f42708f9a3a4ffcTimo Sirainen test_assert(i_stream_stat(filter, TRUE, &st) == 0 &&
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen (uoff_t)st->st_size == size);
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen i_stream_skip(filter, size);
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen i_stream_seek(filter, 0);
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen while (i_stream_read(filter) > 0) ;
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen data = i_stream_get_data(filter, &size);
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen test_assert(size == output_len && memcmp(data, output, size) == 0);
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen test_assert(i_stream_stat(filter, TRUE, &st) == 0 &&
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen (uoff_t)st->st_size == size);
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen i_stream_unref(&filter);
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen i_stream_unref(&istream);
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen test_end();
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen}
de12ff295bb3d0873b4dced5840612cbacd635efTimo Sirainen
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainenstatic void add_random_text(string_t *dest, unsigned int count)
de12ff295bb3d0873b4dced5840612cbacd635efTimo Sirainen{
de12ff295bb3d0873b4dced5840612cbacd635efTimo Sirainen unsigned int i;
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen
de12ff295bb3d0873b4dced5840612cbacd635efTimo Sirainen for (i = 0; i < count; i++)
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen str_append_c(dest, rand() % ('z'-'a'+1) + 'a');
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen}
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainenstatic void ATTR_NULL(3)
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainenfilter2_callback(struct header_filter_istream *input ATTR_UNUSED,
de12ff295bb3d0873b4dced5840612cbacd635efTimo Sirainen struct message_header_line *hdr,
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen bool *matched, void *context ATTR_UNUSED)
de12ff295bb3d0873b4dced5840612cbacd635efTimo Sirainen{
de12ff295bb3d0873b4dced5840612cbacd635efTimo Sirainen if (hdr != NULL && strcmp(hdr->name, "To") == 0)
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen *matched = TRUE;
de12ff295bb3d0873b4dced5840612cbacd635efTimo Sirainen}
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainenstatic void test_istream_filter_large_buffer(void)
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen{
5626ae5e3316eced244adb6485c0927f1c7fdc41Timo Sirainen string_t *input, *output;
5626ae5e3316eced244adb6485c0927f1c7fdc41Timo Sirainen struct istream *istream, *filter;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen const struct stat *st;
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen const unsigned char *data;
5626ae5e3316eced244adb6485c0927f1c7fdc41Timo Sirainen size_t size, prefix_len;
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen const char *p;
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen unsigned int i;
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen test_begin("i_stream_create_header_filter(large buffer)");
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen input = str_new(default_pool, 1024*128);
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen output = str_new(default_pool, 1024*128);
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen str_append(input, "From: ");
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen add_random_text(input, 1024*31);
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen str_append(input, "\nTo: ");
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen add_random_text(input, 1024*32);
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen str_append(input, "\nSubject: ");
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen add_random_text(input, 1024*34);
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen str_append(input, "\n\nbody\n");
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen istream = test_istream_create_data(str_data(input), str_len(input));
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen test_istream_set_max_buffer_size(istream, 8192);
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen filter = i_stream_create_header_filter(istream,
f23298fea47eecbeded985ee2537a34c4c4ef56bTimo Sirainen HEADER_FILTER_EXCLUDE |
f23298fea47eecbeded985ee2537a34c4c4ef56bTimo Sirainen HEADER_FILTER_NO_CR,
f23298fea47eecbeded985ee2537a34c4c4ef56bTimo Sirainen NULL, 0,
287ba82a8da3eaa473b5735d4eeac2fb4c5d8117Timo Sirainen filter2_callback,
f23298fea47eecbeded985ee2537a34c4c4ef56bTimo Sirainen (void *)NULL);
f23298fea47eecbeded985ee2537a34c4c4ef56bTimo Sirainen
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen for (i = 0; i < 2; i++) {
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen for (;;) {
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen ssize_t ret = i_stream_read(filter);
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen i_assert(ret != 0);
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen if (ret == -1)
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen break;
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen if (ret == -2) {
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen data = i_stream_get_data(filter, &size);
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen str_append_n(output, data, size);
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen i_stream_skip(filter, size);
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen }
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen }
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen data = i_stream_get_data(filter, &size);
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen test_assert(size <= 8192);
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen str_append_n(output, data, size);
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen p = strstr(str_c(input), "To: ");
367c05967091a2cbfce59b7f274f55b1a0f9e8c9Timo Sirainen i_assert(p != NULL);
287ba82a8da3eaa473b5735d4eeac2fb4c5d8117Timo Sirainen prefix_len = p - str_c(input);
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen test_assert(strncmp(str_c(input), str_c(output), prefix_len) == 0);
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen
367c05967091a2cbfce59b7f274f55b1a0f9e8c9Timo Sirainen p = strchr(p, '\n');
367c05967091a2cbfce59b7f274f55b1a0f9e8c9Timo Sirainen i_assert(p != NULL);
367c05967091a2cbfce59b7f274f55b1a0f9e8c9Timo Sirainen test_assert(strcmp(p+1, str_c(output) + prefix_len) == 0);
367c05967091a2cbfce59b7f274f55b1a0f9e8c9Timo Sirainen
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen test_assert(i_stream_stat(filter, TRUE, &st) == 0 &&
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen (uoff_t)st->st_size == filter->v_offset + size);
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen /* seek back and retry once with caching and different
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen buffer size */
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen i_stream_seek(filter, 0);
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen str_truncate(output, 0);
287ba82a8da3eaa473b5735d4eeac2fb4c5d8117Timo Sirainen test_istream_set_max_buffer_size(istream, 4096);
287ba82a8da3eaa473b5735d4eeac2fb4c5d8117Timo Sirainen }
287ba82a8da3eaa473b5735d4eeac2fb4c5d8117Timo Sirainen
287ba82a8da3eaa473b5735d4eeac2fb4c5d8117Timo Sirainen str_free(&input);
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen str_free(&output);
1175f27441385a7011629f295f42708f9a3a4ffcTimo Sirainen i_stream_unref(&filter);
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen i_stream_unref(&istream);
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen test_end();
287ba82a8da3eaa473b5735d4eeac2fb4c5d8117Timo Sirainen}
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen
287ba82a8da3eaa473b5735d4eeac2fb4c5d8117Timo Sirainenstatic void
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainenfilter3_callback(struct header_filter_istream *input ATTR_UNUSED,
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen struct message_header_line *hdr,
287ba82a8da3eaa473b5735d4eeac2fb4c5d8117Timo Sirainen bool *matched ATTR_UNUSED, string_t *dest)
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen{
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen if (hdr != NULL)
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen message_header_line_write(dest, hdr);
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen}
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainenstatic void test_istream_callbacks(void)
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen{
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen string_t *input, *output;
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen const struct stat *st;
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen struct istream *istream, *filter;
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen unsigned int i;
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen test_begin("i_stream_create_header_filter(callbacks)");
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen input = str_new(default_pool, 1024*128);
287ba82a8da3eaa473b5735d4eeac2fb4c5d8117Timo Sirainen output = str_new(default_pool, 1024*128);
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen str_append(input, "From: first line\n ");
287ba82a8da3eaa473b5735d4eeac2fb4c5d8117Timo Sirainen add_random_text(input, 1024*31);
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen str_append(input, "\nTo: first line\n\tsecond line\n\t");
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen add_random_text(input, 1024*32);
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen str_append(input, "\n last line\nSubject: ");
287ba82a8da3eaa473b5735d4eeac2fb4c5d8117Timo Sirainen add_random_text(input, 1024*34);
1175f27441385a7011629f295f42708f9a3a4ffcTimo Sirainen str_append(input, "\n");
b79ec51bdeef6ef950eb5e890e65cc0491cf5fe9Timo Sirainen
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen istream = test_istream_create_data(str_data(input), str_len(input));
053843989f13d9013b265fb401a4bde7e0e6568eTimo Sirainen test_istream_set_max_buffer_size(istream, 8192);
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen filter = i_stream_create_header_filter(istream,
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen HEADER_FILTER_EXCLUDE |
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen HEADER_FILTER_NO_CR,
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen NULL, 0,
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen filter3_callback,
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen output);
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen
287ba82a8da3eaa473b5735d4eeac2fb4c5d8117Timo Sirainen /* callback should be called exactly once for all the header input */
287ba82a8da3eaa473b5735d4eeac2fb4c5d8117Timo Sirainen for (i = 0; i < 2; i++) {
ab286a8b58306eb8d22fc18342b6c199fd428e1eTimo Sirainen while (i_stream_read(filter) != -1)
6a04c5112961c5f4fb2d2f25192b3dc424d62ad0Timo Sirainen i_stream_skip(filter, i_stream_get_data_size(filter));
6a04c5112961c5f4fb2d2f25192b3dc424d62ad0Timo Sirainen }
287ba82a8da3eaa473b5735d4eeac2fb4c5d8117Timo Sirainen
287ba82a8da3eaa473b5735d4eeac2fb4c5d8117Timo Sirainen test_assert(i_stream_stat(filter, TRUE, &st) == 0 &&
287ba82a8da3eaa473b5735d4eeac2fb4c5d8117Timo Sirainen (uoff_t)st->st_size == str_len(output));
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen test_assert(strcmp(str_c(output), str_c(input)) == 0);
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen str_free(&input);
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen str_free(&output);
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen i_stream_unref(&filter);
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen i_stream_unref(&istream);
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen test_end();
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen}
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainenstatic void ATTR_NULL(3)
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainenedit_callback(struct header_filter_istream *input,
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen struct message_header_line *hdr,
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen bool *matched, void *context ATTR_UNUSED)
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen{
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen if (hdr != NULL && strcasecmp(hdr->name, "To") == 0) {
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen /* modify To header */
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen const char *new_to = "To: 123\n";
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen *matched = TRUE;
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen i_stream_header_filter_add(input, new_to, strlen(new_to));
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen }
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen}
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainenstatic void test_istream_edit(void)
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen{
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen const char *input = "From: foo\nTo: bar\n\nhello world\n";
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen const char *output = "From: foo\nTo: 123\n\nhello world\n";
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen struct istream *istream, *filter;
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen test_begin("i_stream_create_header_filter(edit)");
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen istream = test_istream_create(input);
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen filter = i_stream_create_header_filter(istream,
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen HEADER_FILTER_EXCLUDE |
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen HEADER_FILTER_NO_CR,
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen NULL, 0,
287ba82a8da3eaa473b5735d4eeac2fb4c5d8117Timo Sirainen edit_callback, (void *)NULL);
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen test_istream_run(istream, filter, strlen(input), output);
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen i_stream_unref(&filter);
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen i_stream_unref(&istream);
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen
287ba82a8da3eaa473b5735d4eeac2fb4c5d8117Timo Sirainen test_end();
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen}
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainenstatic void test_istream_end_body_with_lf(void)
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen{
6a04c5112961c5f4fb2d2f25192b3dc424d62ad0Timo Sirainen const char *input = "From: foo\n\nhello world";
6a04c5112961c5f4fb2d2f25192b3dc424d62ad0Timo Sirainen const char *output = "From: foo\n\nhello world\n";
6a04c5112961c5f4fb2d2f25192b3dc424d62ad0Timo Sirainen const struct stat *st;
6a04c5112961c5f4fb2d2f25192b3dc424d62ad0Timo Sirainen struct istream *istream, *filter;
6a04c5112961c5f4fb2d2f25192b3dc424d62ad0Timo Sirainen unsigned int i, input_len = strlen(input);
6a04c5112961c5f4fb2d2f25192b3dc424d62ad0Timo Sirainen unsigned int output_len = strlen(output);
6a04c5112961c5f4fb2d2f25192b3dc424d62ad0Timo Sirainen const unsigned char *data;
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen string_t *str = t_str_new(64);
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen size_t size;
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen test_begin("i_stream_create_header_filter(end_body_with_lf)");
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen istream = test_istream_create(input);
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen filter = i_stream_create_header_filter(istream,
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen HEADER_FILTER_EXCLUDE |
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen HEADER_FILTER_NO_CR |
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen HEADER_FILTER_END_BODY_WITH_LF,
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen NULL, 0,
b79ec51bdeef6ef950eb5e890e65cc0491cf5fe9Timo Sirainen *null_header_filter_callback,
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen (void *)NULL);
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen for (i = 1; i < input_len; i++) {
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen test_istream_set_size(istream, i);
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen test_assert(i_stream_read(filter) >= 0);
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen }
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen test_istream_set_size(istream, input_len);
b79ec51bdeef6ef950eb5e890e65cc0491cf5fe9Timo Sirainen test_assert(i_stream_read(filter) > 0);
b79ec51bdeef6ef950eb5e890e65cc0491cf5fe9Timo Sirainen test_assert(i_stream_read(filter) > 0);
b79ec51bdeef6ef950eb5e890e65cc0491cf5fe9Timo Sirainen test_assert(i_stream_read(filter) == -1);
b79ec51bdeef6ef950eb5e890e65cc0491cf5fe9Timo Sirainen
b79ec51bdeef6ef950eb5e890e65cc0491cf5fe9Timo Sirainen data = i_stream_get_data(filter, &size);
b79ec51bdeef6ef950eb5e890e65cc0491cf5fe9Timo Sirainen test_assert(size == output_len && memcmp(data, output, size) == 0);
b79ec51bdeef6ef950eb5e890e65cc0491cf5fe9Timo Sirainen test_assert(i_stream_stat(filter, TRUE, &st) == 0 &&
b79ec51bdeef6ef950eb5e890e65cc0491cf5fe9Timo Sirainen (uoff_t)st->st_size == filter->v_offset + size);
b79ec51bdeef6ef950eb5e890e65cc0491cf5fe9Timo Sirainen
64541374b58e4c702b1926e87df421d180ffa006Timo Sirainen i_stream_skip(filter, size);
64541374b58e4c702b1926e87df421d180ffa006Timo Sirainen i_stream_seek(filter, 0);
64541374b58e4c702b1926e87df421d180ffa006Timo Sirainen for (i = 1; i < input_len; i++) {
64541374b58e4c702b1926e87df421d180ffa006Timo Sirainen test_istream_set_size(istream, i);
64541374b58e4c702b1926e87df421d180ffa006Timo Sirainen test_assert(i_stream_read(filter) >= 0);
64541374b58e4c702b1926e87df421d180ffa006Timo Sirainen
64541374b58e4c702b1926e87df421d180ffa006Timo Sirainen data = i_stream_get_data(filter, &size);
64541374b58e4c702b1926e87df421d180ffa006Timo Sirainen str_append_n(str, data, size);
64541374b58e4c702b1926e87df421d180ffa006Timo Sirainen i_stream_skip(filter, size);
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen }
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen test_istream_set_size(istream, input_len);
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen test_assert(i_stream_read(filter) == 1);
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen test_assert(i_stream_read(filter) == 1);
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen test_assert(i_stream_read(filter) == -1);
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen data = i_stream_get_data(filter, &size);
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen str_append_n(str, data, size);
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen test_assert(strcmp(str_c(str), output) == 0);
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen i_stream_unref(&filter);
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen i_stream_unref(&istream);
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen test_end();
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen}
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainenstatic void test_istream_add_missing_eoh(void)
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen{
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen struct {
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen const char *input;
6a04c5112961c5f4fb2d2f25192b3dc424d62ad0Timo Sirainen const char *output;
6a04c5112961c5f4fb2d2f25192b3dc424d62ad0Timo Sirainen unsigned int extra;
6a04c5112961c5f4fb2d2f25192b3dc424d62ad0Timo Sirainen } tests[] = {
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen { "From: foo", "From: foo\n\n", 1 },
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen { "From: foo\n", "From: foo\n\n", 1 },
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen { "From: foo\n\n", "From: foo\n\n", 1 },
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen { "From: foo\n\nbar", "From: foo\n\nbar", 0 },
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen { "From: foo\r\n", "From: foo\r\n\r\n", 1 },
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen { "From: foo\r\n\r\n", "From: foo\r\n\r\n", 0 },
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen { "From: foo\r\n\r\nbar", "From: foo\r\n\r\nbar", 0 }
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen };
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen struct istream *istream, *filter;
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen unsigned int i;
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen test_begin("i_stream_create_header_filter(add_missing_eoh)");
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen for (i = 0; i < N_ELEMENTS(tests); i++) {
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen istream = test_istream_create(tests[i].input);
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen filter = i_stream_create_header_filter(istream,
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen HEADER_FILTER_EXCLUDE |
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen HEADER_FILTER_CRLF_PRESERVE |
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen HEADER_FILTER_ADD_MISSING_EOH,
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen NULL, 0,
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen *null_header_filter_callback, (void *)NULL);
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen test_istream_run(istream, filter,
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen strlen(tests[i].input) + tests[i].extra,
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen tests[i].output);
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen i_stream_unref(&filter);
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen i_stream_unref(&istream);
6a04c5112961c5f4fb2d2f25192b3dc424d62ad0Timo Sirainen }
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen test_end();
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen}
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainenstatic void test_istream_hide_body(void)
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen{
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen struct {
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen const char *input;
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen const char *output;
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen int extra;
287ba82a8da3eaa473b5735d4eeac2fb4c5d8117Timo Sirainen } tests[] = {
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen { "From: foo", "From: foo", 0 },
6a04c5112961c5f4fb2d2f25192b3dc424d62ad0Timo Sirainen { "From: foo\n", "From: foo\n", 0 },
6a04c5112961c5f4fb2d2f25192b3dc424d62ad0Timo Sirainen { "From: foo\n\n", "From: foo\n\n", 1 },
6a04c5112961c5f4fb2d2f25192b3dc424d62ad0Timo Sirainen { "From: foo\n\nbar", "From: foo\n\n", -2 },
6a04c5112961c5f4fb2d2f25192b3dc424d62ad0Timo Sirainen { "From: foo\r\n", "From: foo\r\n", 0 },
6a04c5112961c5f4fb2d2f25192b3dc424d62ad0Timo Sirainen { "From: foo\r\n\r\n", "From: foo\r\n\r\n", 0 },
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen { "From: foo\r\n\r\nbar", "From: foo\r\n\r\n", -3 }
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen };
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen struct istream *istream, *filter;
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen unsigned int i;
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen test_begin("i_stream_create_header_filter(add_missing_eoh)");
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen for (i = 0; i < N_ELEMENTS(tests); i++) {
6a04c5112961c5f4fb2d2f25192b3dc424d62ad0Timo Sirainen istream = test_istream_create(tests[i].input);
6a04c5112961c5f4fb2d2f25192b3dc424d62ad0Timo Sirainen filter = i_stream_create_header_filter(istream,
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen HEADER_FILTER_EXCLUDE |
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen HEADER_FILTER_CRLF_PRESERVE |
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen HEADER_FILTER_HIDE_BODY,
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen NULL, 0,
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen *null_header_filter_callback, (void *)NULL);
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen test_istream_run(istream, filter,
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen strlen(tests[i].input) + tests[i].extra,
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen tests[i].output);
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen i_stream_unref(&filter);
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen i_stream_unref(&istream);
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen }
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen test_end();
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen}
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainenstatic void ATTR_NULL(3)
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainenstrip_eoh_callback(struct header_filter_istream *input ATTR_UNUSED,
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen struct message_header_line *hdr,
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen bool *matched, void *context ATTR_UNUSED)
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen{
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen if (hdr != NULL && hdr->eoh)
6a04c5112961c5f4fb2d2f25192b3dc424d62ad0Timo Sirainen *matched = FALSE;
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen}
6a04c5112961c5f4fb2d2f25192b3dc424d62ad0Timo Sirainen
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainenstatic void test_istream_strip_eoh(void)
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen{
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen const char *input = "From: foo\nTo: bar\n\nhello world\n";
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen const char *output = "From: foo\nTo: bar\nhello world\n";
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen struct istream *istream, *filter;
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen
6a04c5112961c5f4fb2d2f25192b3dc424d62ad0Timo Sirainen test_begin("i_stream_create_header_filter(edit)");
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen istream = test_istream_create(input);
871c7b8969e8627dc4c8b3e56fd126f948e6bce6Timo Sirainen filter = i_stream_create_header_filter(istream,
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen HEADER_FILTER_EXCLUDE | HEADER_FILTER_NO_CR, NULL, 0,
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen strip_eoh_callback, (void *)NULL);
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen test_istream_run(istream, filter, strlen(input), output);
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen i_stream_unref(&filter);
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen i_stream_unref(&istream);
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen test_end();
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen}
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainenint main(void)
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen{
6a04c5112961c5f4fb2d2f25192b3dc424d62ad0Timo Sirainen static void (*test_functions[])(void) = {
6a04c5112961c5f4fb2d2f25192b3dc424d62ad0Timo Sirainen test_istream_filter,
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen test_istream_filter_large_buffer,
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen test_istream_callbacks,
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen test_istream_edit,
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen test_istream_add_missing_eoh,
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen test_istream_end_body_with_lf,
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen test_istream_hide_body,
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen test_istream_strip_eoh,
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen NULL
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen };
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen return test_run(test_functions);
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen}
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen