test-istream-header-filter.c revision 32e3da4a505b3b258d44abdf4366fbfc95680027
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* Copyright (c) 2007-2016 Dovecot authors, see the included COPYING file */
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainentest_istream_run(struct istream *test_istream, struct istream *filter,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const unsigned char *data;
e4b09b008ab544eb8994beecbfffefa21d855e43Timo Sirainen test_istream_set_size(test_istream, input_len);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen test_assert(size == output_len && memcmp(data, output, size) == 0);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* run again to make sure it's still correct the second time */
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen test_assert(size == output_len && memcmp(data, output, size) == 0);
287ba82a8da3eaa473b5735d4eeac2fb4c5d8117Timo Sirainen test_assert(i_stream_stat(filter, TRUE, &st) == 0 &&
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenfilter_callback(struct header_filter_istream *input ATTR_UNUSED,
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen /* drop 1) first header, 2) X-Drop header */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic void test_istream_filter(void)
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";
ee246b46953e4b94b2f22e093373674fa9155500Timo Sirainen const unsigned char *data;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen test_begin("i_stream_create_header_filter(exclude)");
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen filter = i_stream_create_header_filter(istream,
20a802016205bbcafc90f164f769ea801f88d014Timo Sirainen filter2 = i_stream_create_header_filter(filter,
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen test_assert(size == output_len && memcmp(data, output, size) == 0);
1175f27441385a7011629f295f42708f9a3a4ffcTimo Sirainen test_assert(i_stream_stat(filter, TRUE, &st) == 0 &&
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen test_assert(size == output_len && memcmp(data, output, size) == 0);
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen test_assert(i_stream_stat(filter, TRUE, &st) == 0 &&
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainenstatic void add_random_text(string_t *dest, unsigned int count)
de12ff295bb3d0873b4dced5840612cbacd635efTimo Sirainen unsigned int i;
de12ff295bb3d0873b4dced5840612cbacd635efTimo Sirainen for (i = 0; i < count; i++)
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen str_append_c(dest, rand() % ('z'-'a'+1) + 'a');
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainenfilter2_callback(struct header_filter_istream *input ATTR_UNUSED,
de12ff295bb3d0873b4dced5840612cbacd635efTimo Sirainen if (hdr != NULL && strcmp(hdr->name, "To") == 0)
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainenstatic void test_istream_filter_large_buffer(void)
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen const unsigned char *data;
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen const char *p;
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen unsigned int i;
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen test_begin("i_stream_create_header_filter(large buffer)");
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 filter = i_stream_create_header_filter(istream,
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen for (i = 0; i < 2; i++) {
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen test_assert(strncmp(str_c(input), str_c(output), prefix_len) == 0);
367c05967091a2cbfce59b7f274f55b1a0f9e8c9Timo Sirainen test_assert(strcmp(p+1, str_c(output) + prefix_len) == 0);
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen test_assert(i_stream_stat(filter, TRUE, &st) == 0 &&
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen (uoff_t)st->st_size == filter->v_offset + size);
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen /* seek back and retry once with caching and different
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen buffer size */
287ba82a8da3eaa473b5735d4eeac2fb4c5d8117Timo Sirainen test_istream_set_max_buffer_size(istream, 4096);
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainenfilter3_callback(struct header_filter_istream *input ATTR_UNUSED,
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen unsigned int i;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen test_begin("i_stream_create_header_filter(callbacks)");
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen str_append(input, "\nTo: first line\n\tsecond line\n\t");
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 filter = i_stream_create_header_filter(istream,
287ba82a8da3eaa473b5735d4eeac2fb4c5d8117Timo Sirainen /* callback should be called exactly once for all the header input */
287ba82a8da3eaa473b5735d4eeac2fb4c5d8117Timo Sirainen for (i = 0; i < 2; i++) {
6a04c5112961c5f4fb2d2f25192b3dc424d62ad0Timo Sirainen i_stream_skip(filter, i_stream_get_data_size(filter));
287ba82a8da3eaa473b5735d4eeac2fb4c5d8117Timo Sirainen test_assert(i_stream_stat(filter, TRUE, &st) == 0 &&
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen test_assert(strcmp(str_c(output), str_c(input)) == 0);
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainenedit_callback(struct header_filter_istream *input,
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen if (hdr != NULL && strcasecmp(hdr->name, "To") == 0) {
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen /* modify To header */
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen i_stream_header_filter_add(input, new_to, strlen(new_to));
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainenstatic void test_istream_edit(void)
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";
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen test_begin("i_stream_create_header_filter(edit)");
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen filter = i_stream_create_header_filter(istream,
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen test_istream_run(istream, filter, strlen(input), output);
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainenstatic void test_istream_end_body_with_lf(void)
6a04c5112961c5f4fb2d2f25192b3dc424d62ad0Timo Sirainen const char *input = "From: foo\n\nhello world";
6a04c5112961c5f4fb2d2f25192b3dc424d62ad0Timo Sirainen const char *output = "From: foo\n\nhello world\n";
6a04c5112961c5f4fb2d2f25192b3dc424d62ad0Timo Sirainen const unsigned char *data;
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen test_begin("i_stream_create_header_filter(end_body_with_lf)");
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen filter = i_stream_create_header_filter(istream,
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);
6a04c5112961c5f4fb2d2f25192b3dc424d62ad0Timo Sirainen unsigned int extra;
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen { "From: foo\n\nbar", "From: foo\n\nbar", 0 },
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 unsigned int i;
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen test_begin("i_stream_create_header_filter(add_missing_eoh)");
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen istream = test_istream_create(tests[i].input);
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen filter = i_stream_create_header_filter(istream,
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 unsigned int i;
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen test_begin("i_stream_create_header_filter(add_missing_eoh)");
6a04c5112961c5f4fb2d2f25192b3dc424d62ad0Timo Sirainen istream = test_istream_create(tests[i].input);
6a04c5112961c5f4fb2d2f25192b3dc424d62ad0Timo Sirainen filter = i_stream_create_header_filter(istream,
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainenstrip_eoh_callback(struct header_filter_istream *input ATTR_UNUSED,
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";
6a04c5112961c5f4fb2d2f25192b3dc424d62ad0Timo Sirainen test_begin("i_stream_create_header_filter(edit)");
871c7b8969e8627dc4c8b3e56fd126f948e6bce6Timo Sirainen filter = i_stream_create_header_filter(istream,
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen HEADER_FILTER_EXCLUDE | HEADER_FILTER_NO_CR, NULL, 0,
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen test_istream_run(istream, filter, strlen(input), output);
6a04c5112961c5f4fb2d2f25192b3dc424d62ad0Timo Sirainen static void (*test_functions[])(void) = {