/* Copyright (c) 2007-2018 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "array.h"
#include "str.h"
#include "sha1.h"
#include "hash-format.h"
#include "safe-mkstemp.h"
#include "istream.h"
#include "istream-crlf.h"
#include "istream-attachment-extractor.h"
#include "istream-attachment-connector.h"
#include "ostream.h"
#include "test-common.h"
#include <stdio.h>
#include <unistd.h>
"b adjig sadjg jasidgjiaehga3wht8a3w8ghxjc dsgad hasdghsd gasd ds" \
"jdsoga sjdga0w3tjhawjgsertniq3n5oqerjqw2r89q23h awhrqh835r8a"
#define BINARY_TEXT_LONG_BASE64 \
"d2UgaGF2ZQ1hIGxvdCAKb2YgAGJpbmFyeSBzdHVmZiBpbiBoZXJlCmIgYWRqaWcgc2FkamcgamFz\r\n" \
"aWRnamlhZWhnYTN3aHQ4YTN3OGdoeGpjIGRzZ2FkIGhhc2RnaHNkIGdhc2QgZHNqZHNvZ2Egc2pk\r\n" \
"Z2EwdzN0amhhd2pnc2VydG5pcTNuNW9xZXJqcXcycjg5cTIzaCBhd2hycWg4MzVyOGE="
static const char mail_input[] =
"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"
"\r\n"
"\r\n--bound\r\n"
"Content-Transfer-Encoding: base64\r\n"
"\r\n"
"\r\n--bound--\r\n";
static const char mail_output[] =
"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"
"\r\n"
"\r\n--bound\r\n"
"Content-Transfer-Encoding: base64\r\n"
"\r\n"
"\r\n--bound--\r\n";
static const char *mail_broken_input_body_prefix =
"MIME-Version: 1.0\r\n"
"Content-Type: multipart/alternative;\r\n boundary=\"bound\"\r\n"
"\r\n"
"--bound\r\n"
"Content-Transfer-Encoding: base64\r\n"
"\r\n";
static const char *mail_broken_input_bodies[] = {
/* broken base64 input */
"Zm9vCg=\n",
"Zm9vCg\n",
"Zm9vC\n",
/* extra whitespace */
"Zm9v\n Zm9v\n",
"Zm9v \nZm9v\n",
/* mixed LF vs CRLFs */
"Zm9vYmFy\r\nZm9vYmFy\n",
"Zm9vYmFy\nZm9vYmFy\r\n",
/* line length increases */
"Zm9v\nZm9vYmFy\n",
"Zm9v\nZm9vCg==",
"Zm9v\nZm9vYgo="
};
static const char *mail_nonbroken_input_bodies[] = {
/* suffixes with explicit '=' end */
"Zm9vCg==",
"Zm9vCg==\n",
"Zm9vCg==\r\n",
"Zm9vCg==\nfoo\n",
"Zm9vCg==\r\nfoo\n",
"Zm9vCg== \t\t\n\n",
/* suffixes with shorter line length */
"Zm9vYmFy\nZm9v\n",
"Zm9vYmFy\r\nZm9v\r\n",
"Zm9vYmFy\nZm9v\nfoo\n",
"Zm9vYmFy\r\nZm9v\r\nfoo\n",
"Zm9vYmFy\nZm9v\n \t\t\n\n",
/* suffixes with empty line */
"Zm9v\n\n",
"Zm9v\r\n\r\n",
"Zm9v\n\nfoo\n"
"Zm9v\r\n\nfoo\n"
"Zm9v\r\n\r\nfoo\n"
#if 0
/* the whitespace here could be handled as suffixes, but for now
they're not: */
"Zm9v ",
"Zm9v \n"
#endif
};
struct attachment {
unsigned int base64_blocks_per_line;
};
{
int fd;
if (fd == -1)
return fd;
}
const char **error_r ATTR_UNUSED,
void *context ATTR_UNUSED)
{
struct attachment *a;
if (attachment_data == NULL)
if (!array_is_created(&attachments))
a = array_append_space(&attachments);
i_unreached();
return 0;
}
static int
const char **error_r,
void *context ATTR_UNUSED)
{
*error_r = "test open error";
return -1;
}
const char **error_r ATTR_UNUSED,
void *context ATTR_UNUSED)
{
struct attachment *a;
if (o_stream_finish(output) < 0)
i_unreached();
return 0;
}
static int
void *context ATTR_UNUSED)
{
if (success)
*error = "test output error";
return -1;
}
static struct istream *
{
const struct attachment *a;
const char *error;
array_foreach(&attachments, a) {
a->start_offset, a->encoded_size,
i_unreached();
data += a->decoded_size;
data_size -= a->decoded_size;
}
return istream_attachment_connector_finish(&conn);
}
static void
{
const char *error;
i_unreached();
}
{
const unsigned char *data;
int ret = 0;
/* get hash when directly reading input */
}
/* read through attachment extractor */
i_stream_seek(file_input, 0);
}
/* rebuild the original stream and see if the hash matches */
for (unsigned int i = 0; i < 2; i++) {
}
ret = -1;
/* try again without knowing the message's size */
}
/* try with a wrong message size */
for (int i = 0; i < 2; i++) {
(i == 0 ? 1 : -1));
}
if (array_is_created(&attachments))
return ret;
}
static void test_istream_attachment(void)
{
const unsigned char *data;
int ret;
test_begin("istream attachment");
for (i = 1; i <= sizeof(mail_input); i++) {
test_assert(ret == 0);
}
if (array_is_created(&attachments))
test_end();
}
{
char *mail_text;
const unsigned char *data;
int ret;
bool unchanged;
if (err_type == 1)
else if (err_type == 2)
if (err_type != 0) {
goto cleanup;
}
data += prefix_len;
size -= prefix_len;
if (array_is_created(&attachments))
return unchanged;
}
static void test_istream_attachment_extractor(void)
{
unsigned int i;
test_begin("istream attachment extractor");
for (i = 0; i < N_ELEMENTS(mail_broken_input_bodies); i++)
for (i = 0; i < N_ELEMENTS(mail_nonbroken_input_bodies); i++)
test_end();
}
static void test_istream_attachment_extractor_error(void)
{
unsigned int i;
test_begin("istream attachment extractor error");
for (i = 0; i < N_ELEMENTS(mail_broken_input_bodies); i++)
for (i = 0; i < N_ELEMENTS(mail_nonbroken_input_bodies); i++)
}
test_end();
}
static void test_istream_attachment_connector(void)
{
test_begin("istream attachment connector");
test_end();
}
{
int ret = 0;
lib_init();
if (test_input_stream(file_input) < 0) {
path);
ret = -1;
}
lib_deinit();
return ret;
}
{
static void (*const test_functions[])(void) = {
};
if (argc > 1)
else
return test_run(test_functions);
}