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