summaryrefslogtreecommitdiffstats
path: root/src/lib-mail/test-istream-qp-encoder.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib-mail/test-istream-qp-encoder.c')
-rw-r--r--src/lib-mail/test-istream-qp-encoder.c160
1 files changed, 160 insertions, 0 deletions
diff --git a/src/lib-mail/test-istream-qp-encoder.c b/src/lib-mail/test-istream-qp-encoder.c
new file mode 100644
index 0000000..148fe24
--- /dev/null
+++ b/src/lib-mail/test-istream-qp-encoder.c
@@ -0,0 +1,160 @@
+/* Copyright (c) 2017-2018 Dovecot authors, see the included COPYING file */
+
+#include "test-lib.h"
+#include "str.h"
+#include "istream-private.h"
+#include "istream-qp.h"
+
+#define WHITESPACE10 " \t \t \t"
+#define WHITESPACE70 WHITESPACE10 WHITESPACE10 WHITESPACE10 WHITESPACE10 WHITESPACE10 WHITESPACE10 WHITESPACE10
+
+static const struct {
+ const void *input;
+ const char *output;
+ int stream_errno;
+} tests[] = {
+ { "", "", 0 },
+ { "short test", "short test", 0 },
+ { "C'est une cha\xc3\xaene de test simple", "C'est une cha=C3=AEne de test simple", 0 },
+ {
+ "wrap after 76 characters wrap after 76 characters wrap after 76 characters wrap after 76 characters",
+ "wrap after 76 characters wrap after 76 characters wrap after 76 character=\r\ns wrap after 76 characters",
+ 0
+ },
+ {
+ /* the string is split up to avoid C compilers thinking \x99ed as escape */
+ "P\xc5\x99" "edstavitel\xc3\xa9 francouzsk\xc3\xa9ho lidu, ustanoveni v "
+ "N\xc3\xa1rodn\xc3\xadm shrom\xc3\xa1\xc5\xbe" "d\xc4\x9bn\xc3\xad, domn"
+ "\xc3\xadvaj\xc3\xad" "ce se, \xc5\xbe" "e nev\xc4\x9b" "domost, zapomenut\xc3"
+ "\xad nebo pohrd\xc3\xa1n\xc3\xad lidsk\xc3\xbdmi pr\xc3\xa1vy jsou j"
+ "edin\xc3\xbdmi p\xc5\x99\xc3\xad\xc4\x8dinami ve\xc5\x99" "ejn\xc3\xb"
+ "dch ne\xc5\xa1t\xc4\x9bst\xc3\xad a zkorumpov\xc3\xa1n\xc3\xad vl"
+ "\xc3\xa1" "d, rozhodli se vylo\xc5\xbeit v slavnostn\xc3\xad Deklara"
+ "ci p\xc5\x99irozen\xc3\xa1, nezciziteln\xc3\xa1 a posv\xc3\xa1tn\xc3"
+ "\xa1 pr\xc3\xa1va \xc4\x8dlov\xc4\x9bka za t\xc3\xadm \xc3\xba\xc4"
+ "\x8d" "elem, aby tato Deklarace, neust\xc3\xa1le jsouc p\xc5\x99" "ed o"
+ "\xc4\x8" "dima v\xc5\xa1" "em \xc4\x8dlen\xc5\xafm lidsk\xc3\xa9 spo"
+ "le\xc4\x8dnosti, uv\xc3\xa1" "d\xc4\x9bla jim st\xc3\xa1le na pam\xc4"
+ "\x9b\xc5\xa5 jejich pr\xc3\xa1va a jejich povinnosti; aby \xc4\x8din"
+ "y z\xc3\xa1konod\xc3\xa1rn\xc3\xa9 moci a \xc4\x8diny v\xc3\xbdkonn"
+ "\xc3\xa9 moci mohly b\xc3\xbdt v ka\xc5\xbe" "d\xc3\xa9 chv\xc3\xadli p"
+ "orovn\xc3\xa1v\xc3\xa1ny s \xc3\xba\xc4\x8d" "elem ka\xc5\xbe" "d\xc3"
+ "\xa9 politick\xc3\xa9 instituce a byly v d\xc5\xafsledku toho chov"
+ "\xc3\xa1ny je\xc5\xa1t\xc4\x9b v\xc3\xad" "ce v \xc3\xba" "ct\xc4"
+ "\x9b; aby po\xc5\xbe" "adavky ob\xc4\x8d" "an\xc5\xaf, kdy\xc5\xbe s"
+ "e budou nap\xc5\x99\xc3\xad\xc5\xa1t\xc4\x9b zakl\xc3\xa1" "dat na j"
+ "ednoduch\xc3\xb" "dch a nepop\xc3\xadrateln\xc3\xbd" "ch z\xc3\xa1sa"
+ "d\xc3\xa1" "ch, sm\xc4\x9b\xc5\x99ovaly v\xc5\xb" "edy k zachov\xc3"
+ "\xa1n\xc3\xad \xc3\xbastavy a ku blahu v\xc5\xa1" "ech.",
+ "P=C5=99edstavitel=C3=A9 francouzsk=C3=A9ho lidu, ustanoveni v N=C3=A1rodn=\r\n"
+ "=C3=ADm shrom=C3=A1=C5=BEd=C4=9Bn=C3=AD, domn=C3=ADvaj=C3=ADce se, =C5=BE=\r\n"
+ "e nev=C4=9Bdomost, zapomenut=C3=AD nebo pohrd=C3=A1n=C3=AD lidsk=C3=BDmi=20=\r\n"
+ "pr=C3=A1vy jsou jedin=C3=BDmi p=C5=99=C3=AD=C4=8Dinami ve=C5=99ejn=C3=0Bd=\r\n"
+ "ch ne=C5=A1t=C4=9Bst=C3=AD a zkorumpov=C3=A1n=C3=AD vl=C3=A1d, rozhodli=20=\r\n"
+ "se vylo=C5=BEit v slavnostn=C3=AD Deklaraci p=C5=99irozen=C3=A1, nezcizit=\r\n"
+ "eln=C3=A1 a posv=C3=A1tn=C3=A1 pr=C3=A1va =C4=8Dlov=C4=9Bka za t=C3=ADm=20=\r\n"
+ "=C3=BA=C4=8Delem, aby tato Deklarace, neust=C3=A1le jsouc p=C5=99ed o=C4=\r\n"
+ "=08dima v=C5=A1em =C4=8Dlen=C5=AFm lidsk=C3=A9 spole=C4=8Dnosti, uv=C3=A1=\r\n"
+ "d=C4=9Bla jim st=C3=A1le na pam=C4=9B=C5=A5 jejich pr=C3=A1va a jejich po=\r\n"
+ "vinnosti; aby =C4=8Diny z=C3=A1konod=C3=A1rn=C3=A9 moci a =C4=8Diny v=C3=\r\n"
+ "=BDkonn=C3=A9 moci mohly b=C3=BDt v ka=C5=BEd=C3=A9 chv=C3=ADli porovn=C3=\r\n"
+ "=A1v=C3=A1ny s =C3=BA=C4=8Delem ka=C5=BEd=C3=A9 politick=C3=A9 instituce=20=\r\n"
+ "a byly v d=C5=AFsledku toho chov=C3=A1ny je=C5=A1t=C4=9B v=C3=ADce v =C3=\r\n"
+ "=BAct=C4=9B; aby po=C5=BEadavky ob=C4=8Dan=C5=AF, kdy=C5=BE se budou nap=\r\n"
+ "=C5=99=C3=AD=C5=A1t=C4=9B zakl=C3=A1dat na jednoduch=C3=0Bdch a nepop=C3=\r\n"
+ "=ADrateln=C3=BDch z=C3=A1sad=C3=A1ch, sm=C4=9B=C5=99ovaly v=C5=0Bedy k za=\r\n"
+ "chov=C3=A1n=C3=AD =C3=BAstavy a ku blahu v=C5=A1ech.",
+ 0
+ },
+ /* Test line breaking */
+ { WHITESPACE70"1234567", WHITESPACE70"123=\r\n4567", 0 },
+ { WHITESPACE70" 7", WHITESPACE70" =20=\r\n 7", 0 },
+ { WHITESPACE70""WHITESPACE10"1", WHITESPACE70" =20=\r\n \t \t \t1", 0 },
+
+};
+
+static void
+encode_test(const char *qp_input, const char *output, int stream_errno,
+ unsigned int buffer_size)
+{
+ size_t qp_input_len = strlen(qp_input);
+ struct istream *input_data, *input;
+ const unsigned char *data;
+ size_t i, size;
+ string_t *str = t_str_new(32);
+ int ret = 0;
+
+ input_data = test_istream_create_data(qp_input, qp_input_len);
+ test_istream_set_max_buffer_size(input_data, buffer_size);
+ test_istream_set_allow_eof(input_data, FALSE);
+ input = i_stream_create_qp_encoder(input_data, 0);
+
+ for (i = 1; i <= qp_input_len; i++) {
+ test_istream_set_size(input_data, i);
+ while ((ret = i_stream_read_more(input, &data, &size)) > 0) {
+ str_append_data(str, data, size);
+ i_stream_skip(input, size);
+ }
+ if (ret == -1 && stream_errno != 0)
+ break;
+ test_assert(ret == 0);
+ }
+ if (ret == 0) {
+ test_istream_set_allow_eof(input_data, TRUE);
+ while ((ret = i_stream_read_more(input, &data, &size)) > 0) {
+ str_append_data(str, data, size);
+ i_stream_skip(input, size);
+ }
+ }
+
+ test_assert(ret == -1);
+ test_assert(input->stream_errno == stream_errno);
+ test_assert_strcmp(str_c(str), output);
+
+ if (stream_errno == 0) {
+ /* Test seeking on streams where the testcases do not
+ * expect a specific errno already. */
+ uoff_t v_off = input->v_offset;
+ /* Seeking backwards */
+ i_stream_seek(input, 0);
+ test_assert(input->v_offset == 0);
+
+ /* Seeking forward */
+ i_stream_seek(input, v_off+1);
+ test_assert(input->stream_errno == ESPIPE);
+ }
+
+ i_stream_unref(&input);
+ /* Test closing stream gives expected results */
+ i_stream_seek(input_data, 0);
+ input = i_stream_create_qp_encoder(input_data, 0);
+ i_stream_close(input);
+ test_assert(input->closed);
+ test_assert(i_stream_read_more(input, &data, &size) == -1);
+
+ i_stream_unref(&input);
+ i_stream_unref(&input_data);
+}
+
+static void test_istream_qp_encoder(void)
+{
+ unsigned int i, j;
+
+ for (i = 0; i < N_ELEMENTS(tests); i++) {
+ test_begin(t_strdup_printf("istream qp encoder %u", i+1));
+ for (j = 1; j < 10; j++) T_BEGIN {
+ encode_test(tests[i].input, tests[i].output,
+ tests[i].stream_errno, j);
+ } T_END;
+ test_end();
+ }
+}
+
+int main(void)
+{
+ static void (*const test_functions[])(void) = {
+ test_istream_qp_encoder,
+ NULL
+ };
+ return test_run(test_functions);
+}