summaryrefslogtreecommitdiffstats
path: root/src/lib-mail/test-istream-binary-converter.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/lib-mail/test-istream-binary-converter.c215
1 files changed, 215 insertions, 0 deletions
diff --git a/src/lib-mail/test-istream-binary-converter.c b/src/lib-mail/test-istream-binary-converter.c
new file mode 100644
index 0000000..c32dcb0
--- /dev/null
+++ b/src/lib-mail/test-istream-binary-converter.c
@@ -0,0 +1,215 @@
+/* Copyright (c) 2007-2018 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "base64.h"
+#include "buffer.h"
+#include "str.h"
+#include "sha1.h"
+#include "istream.h"
+#include "istream-crlf.h"
+#include "istream-binary-converter.h"
+#include "test-common.h"
+
+#include <stdio.h>
+
+#define BINARY_TEXT_LONG "we have\ra lot \nof \0binary stuff in here\n" \
+"b adjig sadjg jasidgjiaehga3wht8a3w8ghxjc dsgad hasdghsd gasd ds" \
+"jdsoga sjdga0w3tjhawjgsertniq3n5oqerjqw2r89q23h awhrqh835r8a"
+#define BINARY_TEXT_LONG_BASE64 \
+"d2UgaGF2ZQ1hIGxvdCAKb2YgAGJpbmFyeSBzdHVmZiBpbiBoZXJlCmIgYWRqaWcgc2FkamcgamFz\r\n" \
+"aWRnamlhZWhnYTN3aHQ4YTN3OGdoeGpjIGRzZ2FkIGhhc2RnaHNkIGdhc2QgZHNqZHNvZ2Egc2pk\r\n" \
+"Z2EwdzN0amhhd2pnc2VydG5pcTNuNW9xZXJqcXcycjg5cTIzaCBhd2hycWg4MzVyOGE="
+
+#define BINARY_TEXT_SHORT "eh"
+#define BINARY_TEXT_SHORT_BASE64 "ZWg="
+
+static const char mail_input_mime[] =
+"MIME-Version: 1.0\r\n"
+"Content-Type: multipart/alternative;\r\n boundary=\"bound\"\r\n"
+"\r\n"
+"mime header\r\n"
+"\r\n--bound\r\n"
+"Content-Transfer-Encoding: binary\r\n"
+"Content-Type: text/plain\r\n"
+"\r\n"
+BINARY_TEXT_LONG
+"\r\n--bound\r\n"
+"Content-Type: text/plain\r\n"
+"Content-Transfer-Encoding: binary\r\n"
+"\r\n"
+BINARY_TEXT_SHORT
+"\n--bound\r\n"
+"Content-Type: text/plain\r\n"
+"\r\n"
+"hello world\r\n"
+"\r\n--bound--\r\n";
+
+static const char mail_output_mime[] =
+"MIME-Version: 1.0\r\n"
+"Content-Type: multipart/alternative;\r\n boundary=\"bound\"\r\n"
+"\r\n"
+"mime header\r\n"
+"\r\n--bound\r\n"
+"Content-Transfer-Encoding: base64\r\n"
+"Content-Type: text/plain\r\n"
+"\r\n"
+BINARY_TEXT_LONG_BASE64
+"\r\n--bound\r\n"
+"Content-Type: text/plain\r\n"
+"Content-Transfer-Encoding: base64\r\n"
+"\r\n"
+BINARY_TEXT_SHORT_BASE64
+"\n--bound\r\n"
+"Content-Type: text/plain\r\n"
+"\r\n"
+"hello world\r\n"
+"\r\n--bound--\r\n";
+
+static const char mail_input_root_hdr[] =
+"MIME-Version: 1.0\r\n"
+"Content-Transfer-Encoding: binary\r\n"
+"Content-Type: text/plain\r\n"
+"\r\n";
+
+static const char mail_output_root_hdr[] =
+"MIME-Version: 1.0\r\n"
+"Content-Transfer-Encoding: base64\r\n"
+"Content-Type: text/plain\r\n"
+"\r\n";
+
+static const char mail_root_nonbinary[] =
+"MIME-Version: 1.0\r\n"
+"Content-Type: text/plain\r\n"
+"\r\n"
+"hello\n\n";
+
+static void
+test_istream_binary_converter_test(const char *mail_input, unsigned int mail_input_len,
+ const char *mail_output, unsigned int mail_output_len,
+ unsigned int idx)
+{
+ struct istream *datainput, *input;
+ const unsigned char *data;
+ size_t i, size;
+ int ret;
+
+ datainput = test_istream_create_data(mail_input, mail_input_len);
+ test_istream_set_allow_eof(datainput, FALSE);
+ input = i_stream_create_binary_converter(datainput);
+
+ for (i = 1; i <= mail_input_len; i++) {
+ test_istream_set_size(datainput, i);
+ while ((ret = i_stream_read(input)) > 0) ;
+ test_assert_idx(ret == 0, idx);
+ }
+ test_istream_set_allow_eof(datainput, TRUE);
+ while ((ret = i_stream_read(input)) > 0) ;
+ test_assert_idx(ret == -1, idx);
+
+ data = i_stream_get_data(input, &size);
+ test_assert_idx(size == mail_output_len &&
+ memcmp(data, mail_output, size) == 0, idx);
+ i_stream_unref(&input);
+ i_stream_unref(&datainput);
+}
+
+static void test_istream_binary_converter_mime(void)
+{
+ test_begin("istream binary converter in mime parts");
+ test_istream_binary_converter_test(mail_input_mime, sizeof(mail_input_mime)-1,
+ mail_output_mime, sizeof(mail_output_mime)-1, 0);
+ test_end();
+}
+
+static void test_istream_binary_converter_root(void)
+{
+ buffer_t *inbuf = t_buffer_create(512);
+ buffer_t *outbuf = t_buffer_create(512);
+ const char *const suffixes[] = { "\n", "\r\n", "\n\r\n\n\n" };
+ unsigned int i;
+ unsigned int input_hdr_len = sizeof(mail_input_root_hdr)-1;
+
+ test_begin("istream binary converter in root");
+ buffer_append(inbuf, mail_input_root_hdr, input_hdr_len);
+ buffer_append(outbuf, mail_output_root_hdr, sizeof(mail_output_root_hdr)-1);
+ for (i = 0; i < N_ELEMENTS(suffixes); i++) {
+ buffer_set_used_size(inbuf, input_hdr_len);
+ buffer_set_used_size(outbuf, sizeof(mail_output_root_hdr)-1);
+ buffer_append(inbuf, BINARY_TEXT_SHORT, sizeof(BINARY_TEXT_SHORT)-1);
+ buffer_append(inbuf, suffixes[i], strlen(suffixes[i]));
+ base64_encode(CONST_PTR_OFFSET(inbuf->data, input_hdr_len),
+ inbuf->used - input_hdr_len, outbuf);
+ test_istream_binary_converter_test(inbuf->data, inbuf->used,
+ outbuf->data, outbuf->used, i);
+ }
+ test_end();
+}
+
+static void test_istream_binary_converter_root_nonbinary(void)
+{
+ test_begin("istream binary converter in root having non-binary");
+ test_istream_binary_converter_test(mail_root_nonbinary, sizeof(mail_root_nonbinary)-1,
+ mail_root_nonbinary, sizeof(mail_root_nonbinary)-1, 0);
+ test_end();
+}
+
+static int test_input_file(const char *path)
+{
+ struct istream *file_input, *input, *input2;
+ const unsigned char *data;
+ size_t size;
+ struct sha1_ctxt hash;
+ unsigned char hash_file[SHA1_RESULTLEN], hash_converter[SHA1_RESULTLEN];
+ int ret = 0;
+
+ lib_init();
+
+ file_input = i_stream_create_file(path, 64);
+
+ /* get hash when directly reading input */
+ input = i_stream_create_crlf(file_input);
+ sha1_init(&hash);
+ while (i_stream_read_more(input, &data, &size) > 0) {
+ sha1_loop(&hash, data, size);
+ i_stream_skip(input, size);
+ }
+ sha1_result(&hash, hash_file);
+ i_stream_unref(&input);
+
+ /* get hash when going through converter */
+ i_stream_seek(file_input, 0);
+ input = i_stream_create_crlf(file_input);
+ input2 = i_stream_create_binary_converter(input);
+ sha1_init(&hash);
+ while (i_stream_read_more(input2, &data, &size) > 0) {
+ sha1_loop(&hash, data, size);
+ i_stream_skip(input2, size);
+ }
+ sha1_result(&hash, hash_converter);
+ i_stream_unref(&input2);
+ i_stream_unref(&input);
+
+ if (memcmp(hash_file, hash_converter, SHA1_RESULTLEN) != 0) {
+ fprintf(stderr, "istream-binary-converter: mismatch on file %s\n",
+ path);
+ ret = 1;
+ }
+
+ i_stream_unref(&file_input);
+ lib_deinit();
+ return ret;
+}
+
+int main(int argc, char *argv[])
+{
+ static void (*const test_functions[])(void) = {
+ test_istream_binary_converter_mime,
+ test_istream_binary_converter_root,
+ test_istream_binary_converter_root_nonbinary,
+ NULL
+ };
+ if (argc > 1)
+ return test_input_file(argv[1]);
+ else
+ return test_run(test_functions);
+}