static int fetch_text_utf8(struct fetch_cmd_context *ctx)
{
+ const struct message_parser_settings parser_set = {
+ .hdr_flags = MESSAGE_HEADER_PARSER_FLAG_CLEAN_ONELINE,
+ };
struct istream *input;
struct message_parser_ctx *parser;
struct message_decoder_context *decoder;
if (mail_get_stream(ctx->mail, NULL, NULL, &input) < 0)
return -1;
- parser = message_parser_init(pool_datastack_create(), input,
- MESSAGE_HEADER_PARSER_FLAG_CLEAN_ONELINE,
- 0);
+ parser = message_parser_init(pool_datastack_create(), input, &parser_set);
decoder = message_decoder_init(NULL, 0);
while ((ret = message_parser_parse_next_block(parser, &raw_block)) > 0) {
static struct message_part *
msg_parse(pool_t pool, const char *message, bool parse_bodystructure)
{
+ const struct message_parser_settings parser_set = {
+ .hdr_flags = MESSAGE_HEADER_PARSER_FLAG_SKIP_INITIAL_LWSP |
+ MESSAGE_HEADER_PARSER_FLAG_DROP_CR,
+ .flags = MESSAGE_PARSER_FLAG_SKIP_BODY_BLOCK,
+ };
struct message_parser_ctx *parser;
struct istream *input;
struct message_block block;
int ret;
input = i_stream_create_from_data(message, strlen(message));
- parser = message_parser_init(pool, input,
- MESSAGE_HEADER_PARSER_FLAG_SKIP_INITIAL_LWSP |
- MESSAGE_HEADER_PARSER_FLAG_DROP_CR,
- MESSAGE_PARSER_FLAG_SKIP_BODY_BLOCK);
+ parser = message_parser_init(pool, input, &parser_set);
while ((ret = message_parser_parse_next_block(parser, &block)) > 0) {
if (parse_bodystructure) {
message_part_data_parse_from_header(pool, block.part,
static struct message_part_envelope *
msg_parse(pool_t pool, const char *message)
{
+ const struct message_parser_settings parser_set = {
+ .hdr_flags = MESSAGE_HEADER_PARSER_FLAG_SKIP_INITIAL_LWSP |
+ MESSAGE_HEADER_PARSER_FLAG_DROP_CR,
+ .flags = MESSAGE_PARSER_FLAG_SKIP_BODY_BLOCK,
+ };
struct message_parser_ctx *parser;
struct message_part_envelope *envlp = NULL;
struct istream *input;
int ret;
input = i_stream_create_from_data(message, strlen(message));
- parser = message_parser_init(pool, input,
- MESSAGE_HEADER_PARSER_FLAG_SKIP_INITIAL_LWSP |
- MESSAGE_HEADER_PARSER_FLAG_DROP_CR,
- MESSAGE_PARSER_FLAG_SKIP_BODY_BLOCK);
+ parser = message_parser_init(pool, input, &parser_set);
while ((ret = message_parser_parse_next_block(parser, &block)) > 0) {
i_assert(block.part->parent == NULL);
message_part_envelope_parse_from_header(pool, &envlp, block.hdr);
struct istream_attachment_settings *set,
void *context)
{
+ const struct message_parser_settings parser_set = {
+ .flags = MESSAGE_PARSER_FLAG_INCLUDE_MULTIPART_BLOCKS |
+ MESSAGE_PARSER_FLAG_INCLUDE_BOUNDARIES,
+ };
struct attachment_istream *astream;
i_assert(set->min_size > 0);
astream->istream.istream.seekable = FALSE;
astream->pool = pool_alloconly_create("istream attachment", 1024);
- astream->parser = message_parser_init(astream->pool, input, 0,
- MESSAGE_PARSER_FLAG_INCLUDE_MULTIPART_BLOCKS |
- MESSAGE_PARSER_FLAG_INCLUDE_BOUNDARIES);
+ astream->parser = message_parser_init(astream->pool, input, &parser_set);
return i_stream_create(&astream->istream, input,
i_stream_get_fd(input), 0);
}
struct istream *i_stream_create_binary_converter(struct istream *input)
{
+ const struct message_parser_settings parser_set = {
+ .flags = MESSAGE_PARSER_FLAG_INCLUDE_MULTIPART_BLOCKS |
+ MESSAGE_PARSER_FLAG_INCLUDE_BOUNDARIES,
+ };
struct binary_converter_istream *bstream;
bstream = i_new(struct binary_converter_istream, 1);
bstream->istream.istream.seekable = FALSE;
bstream->pool = pool_alloconly_create("istream binary converter", 128);
- bstream->parser = message_parser_init(bstream->pool, input, 0,
- MESSAGE_PARSER_FLAG_INCLUDE_MULTIPART_BLOCKS |
- MESSAGE_PARSER_FLAG_INCLUDE_BOUNDARIES);
+ bstream->parser = message_parser_init(bstream->pool, input, &parser_set);
return i_stream_create(&bstream->istream, input,
i_stream_get_fd(input), 0);
}
struct message_parser_ctx *
message_parser_init_from_parts(struct message_part *parts,
struct istream *input,
- enum message_header_parser_flags hdr_flags,
- enum message_parser_flags flags)
+ const struct message_parser_settings *set)
{
struct message_parser_ctx *ctx;
i_assert(parts != NULL);
- ctx = message_parser_init_int(input, hdr_flags, flags);
+ ctx = message_parser_init_int(input, set);
ctx->preparsed = TRUE;
ctx->parts = ctx->part = parts;
ctx->parse_next_block = preparsed_parse_next_header_init;
struct message_parser_ctx *
message_parser_init_int(struct istream *input,
- enum message_header_parser_flags hdr_flags,
- enum message_parser_flags flags);
+ const struct message_parser_settings *set);
int message_parser_read_more(struct message_parser_ctx *ctx,
struct message_block *block_r, bool *full_r);
struct message_parser_ctx *
message_parser_init_int(struct istream *input,
- enum message_header_parser_flags hdr_flags,
- enum message_parser_flags flags)
+ const struct message_parser_settings *set)
{
struct message_parser_ctx *ctx;
ctx = i_new(struct message_parser_ctx, 1);
- ctx->hdr_flags = hdr_flags;
- ctx->flags = flags;
+ ctx->hdr_flags = set->hdr_flags;
+ ctx->flags = set->flags;
ctx->input = input;
i_stream_ref(input);
return ctx;
struct message_parser_ctx *
message_parser_init(pool_t part_pool, struct istream *input,
- enum message_header_parser_flags hdr_flags,
- enum message_parser_flags flags)
+ const struct message_parser_settings *set)
{
struct message_parser_ctx *ctx;
- ctx = message_parser_init_int(input, hdr_flags, flags);
+ ctx = message_parser_init_int(input, set);
ctx->part_pool = part_pool;
ctx->parts = ctx->part = p_new(part_pool, struct message_part, 1);
ctx->next_part = &ctx->part->children;
MESSAGE_PARSER_FLAG_INCLUDE_BOUNDARIES = 0x08
};
+struct message_parser_settings {
+ enum message_header_parser_flags hdr_flags;
+ enum message_parser_flags flags;
+};
+
struct message_parser_ctx;
struct message_block {
are allocated from. */
struct message_parser_ctx *
message_parser_init(pool_t part_pool, struct istream *input,
- enum message_header_parser_flags hdr_flags,
- enum message_parser_flags flags);
+ const struct message_parser_settings *set);
/* Deinitialize message parser. The ctx must NOT have been created by
message_parser_init_from_parts(). */
void message_parser_deinit(struct message_parser_ctx **ctx,
struct message_parser_ctx *
message_parser_init_from_parts(struct message_part *parts,
struct istream *input,
- enum message_header_parser_flags hdr_flags,
- enum message_parser_flags flags);
+ const struct message_parser_settings *set);
/* Same as message_parser_deinit(), but return an error message describing
why the preparsed parts didn't match the message. This can also safely be
called even when preparsed parts weren't used - it'll always just return
struct istream *input, struct message_part *parts,
const char **error_r)
{
- const enum message_header_parser_flags hdr_parser_flags =
- MESSAGE_HEADER_PARSER_FLAG_CLEAN_ONELINE;
+ const struct message_parser_settings parser_set = {
+ .hdr_flags = MESSAGE_HEADER_PARSER_FLAG_CLEAN_ONELINE,
+ };
struct message_parser_ctx *parser_ctx;
struct message_block raw_block;
struct message_part *new_parts;
if (parts != NULL) {
parser_ctx = message_parser_init_from_parts(parts,
- input, hdr_parser_flags, 0);
+ input, &parser_set);
} else {
parser_ctx = message_parser_init(pool_datastack_create(),
- input, hdr_parser_flags, 0);
+ input, &parser_set);
}
while ((ret = message_parser_parse_next_block(parser_ctx,
unsigned int max_snippet_chars,
string_t *snippet)
{
+ const struct message_parser_settings parser_set = { .flags = 0 };
struct message_parser_ctx *parser;
struct message_part *parts;
struct message_decoder_context *decoder;
ctx.snippet.chars_left = max_snippet_chars;
ctx.quoted_snippet.snippet = str_new(pool, max_snippet_chars);
ctx.quoted_snippet.chars_left = max_snippet_chars - 1; /* -1 for '>' */
- parser = message_parser_init(pool_datastack_create(), input, 0, 0);
+ parser = message_parser_init(pool_datastack_create(), input, &parser_set);
decoder = message_decoder_init(NULL, 0);
while ((ret = message_parser_parse_next_block(parser, &raw_block)) > 0) {
if (!message_decoder_decode_next_block(decoder, &raw_block, &block))
"\n"
"?garbage\n"
"--foo--\n";
+ const struct message_parser_settings parser_set = { .flags = 0, };
struct message_parser_ctx *parser;
struct message_decoder_context *decoder;
struct message_part *parts;
test_begin("message decoder multipart");
istream = test_istream_create(test_message_input);
- parser = message_parser_init(pool_datastack_create(), istream, 0, 0);
+ parser = message_parser_init(pool_datastack_create(), istream,
+ &parser_set);
decoder = message_decoder_init(NULL, 0);
test_istream_set_allow_eof(istream, FALSE);
"\n";
#define TEST_MSG_LEN (sizeof(test_msg)-1)
+static const struct message_parser_settings set_empty = { .flags = 0 };
+
static bool msg_parts_cmp(struct message_part *p1, struct message_part *p2)
{
while (p1 != NULL || p2 != NULL) {
static void test_parsed_parts(struct istream *input, struct message_part *parts)
{
+ const struct message_parser_settings parser_set = {
+ .flags = MESSAGE_PARSER_FLAG_SKIP_BODY_BLOCK,
+ };
struct message_parser_ctx *parser;
struct message_block block;
struct message_part *parts2;
if (i_stream_get_size(input, TRUE, &input_size) < 0)
i_unreached();
- parser = message_parser_init_from_parts(parts, input, 0,
- MESSAGE_PARSER_FLAG_SKIP_BODY_BLOCK);
+ parser = message_parser_init_from_parts(parts, input, &parser_set);
for (i = 1; i <= input_size*2+1; i++) {
test_istream_set_size(input, i/2);
if (i > TEST_MSG_LEN*2)
output = t_str_new(128);
/* full parsing */
- parser = message_parser_init(pool, input, 0,
- MESSAGE_PARSER_FLAG_INCLUDE_MULTIPART_BLOCKS |
- MESSAGE_PARSER_FLAG_INCLUDE_BOUNDARIES);
+ const struct message_parser_settings full_parser_set = {
+ .flags = MESSAGE_PARSER_FLAG_INCLUDE_MULTIPART_BLOCKS |
+ MESSAGE_PARSER_FLAG_INCLUDE_BOUNDARIES,
+ };
+ parser = message_parser_init(pool, input, &full_parser_set);
while ((ret = message_parser_parse_next_block(parser, &block)) > 0) {
if (block.hdr != NULL)
message_header_line_write(output, block.hdr);
i_stream_seek(input, 0);
test_istream_set_allow_eof(input, FALSE);
- parser = message_parser_init(pool, input, 0, 0);
+ parser = message_parser_init(pool, input, &set_empty);
for (i = 1; i <= TEST_MSG_LEN*2+1; i++) {
test_istream_set_size(input, i/2);
if (i > TEST_MSG_LEN*2)
test_istream_set_allow_eof(input, FALSE);
end_of_headers_idx = (strstr(test_msg, "\n-----") - test_msg);
- parser = message_parser_init_from_parts(parts, input, 0,
- MESSAGE_PARSER_FLAG_SKIP_BODY_BLOCK);
+ const struct message_parser_settings preparsed_parser_set = {
+ .flags = MESSAGE_PARSER_FLAG_SKIP_BODY_BLOCK,
+ };
+ parser = message_parser_init_from_parts(parts, input,
+ &preparsed_parser_set);
for (i = 1; i <= TEST_MSG_LEN*2+1; i++) {
test_istream_set_size(input, i/2);
if (i > TEST_MSG_LEN*2)
pool = pool_alloconly_create("message parser", 10240);
input = test_istream_create(input_msg);
- parser = message_parser_init(pool, input, 0, 0);
+ parser = message_parser_init(pool, input, &set_empty);
while ((ret = message_parser_parse_next_block(parser, &block)) > 0) ;
test_assert(ret < 0);
message_parser_deinit(&parser, &parts);
pool = pool_alloconly_create("message parser", 10240);
input = test_istream_create(input_msg);
- parser = message_parser_init(pool, input, 0, 0);
+ parser = message_parser_init(pool, input, &set_empty);
while ((ret = message_parser_parse_next_block(parser, &block)) > 0) ;
test_assert(ret < 0);
message_parser_deinit(&parser, &parts);
pool = pool_alloconly_create("message parser", 10240);
input = test_istream_create(input_msg);
- parser = message_parser_init(pool, input, 0, 0);
+ parser = message_parser_init(pool, input, &set_empty);
while ((ret = message_parser_parse_next_block(parser, &block)) > 0) ;
test_assert(ret < 0);
message_parser_deinit(&parser, &parts);
pool = pool_alloconly_create("message parser", 10240);
input = test_istream_create(input_msg);
- parser = message_parser_init(pool, input, 0, 0);
+ parser = message_parser_init(pool, input, &set_empty);
while ((ret = message_parser_parse_next_block(parser, &block)) > 0) ;
test_assert(ret < 0);
message_parser_deinit(&parser, &parts);
pool = pool_alloconly_create("message parser", 10240);
input = test_istream_create(input_msg);
- parser = message_parser_init(pool, input, 0, 0);
+ parser = message_parser_init(pool, input, &set_empty);
while ((ret = message_parser_parse_next_block(parser, &block)) > 0) ;
test_assert(ret < 0);
message_parser_deinit(&parser, &parts);
pool = pool_alloconly_create("message parser", 10240);
input = test_istream_create(input_msg);
- parser = message_parser_init(pool, input, 0, 0);
+ parser = message_parser_init(pool, input, &set_empty);
while ((ret = message_parser_parse_next_block(parser, &block)) > 0) ;
test_assert(ret < 0);
message_parser_deinit(&parser, &parts);
pool = pool_alloconly_create("message parser", 10240);
input = test_istream_create(input_msg);
- parser = message_parser_init(pool, input, 0, 0);
+ parser = message_parser_init(pool, input, &set_empty);
while ((ret = message_parser_parse_next_block(parser, &block)) > 0) ;
test_assert(ret < 0);
message_parser_deinit(&parser, &parts);
pool = pool_alloconly_create("message parser", 10240);
input = test_istream_create(input_msg);
- parser = message_parser_init(pool, input, 0, 0);
+ parser = message_parser_init(pool, input, &set_empty);
while ((ret = message_parser_parse_next_block(parser, &block)) > 0) ;
test_assert(ret < 0);
message_parser_deinit(&parser, &parts);
pool = pool_alloconly_create("message parser", 10240);
input = test_istream_create(input_msg);
- parser = message_parser_init(pool, input, 0, 0);
+ parser = message_parser_init(pool, input, &set_empty);
while ((ret = message_parser_parse_next_block(parser, &block)) > 0) ;
test_assert(ret < 0);
message_parser_deinit(&parser, &parts);
pool = pool_alloconly_create("message parser", 10240);
input = test_istream_create(input_msg);
- parser = message_parser_init(pool, input, 0, 0);
+ parser = message_parser_init(pool, input, &set_empty);
test_assert(message_parser_parse_next_block(parser, &block) > 0 &&
block.hdr != NULL && strcmp(block.hdr->name, "a") == 0 &&
block.hdr->value_len == 1 && block.hdr->value[0] == 'b');
pool = pool_alloconly_create("message parser", 10240);
input = test_istream_create(input_msg);
- parser = message_parser_init(pool, input, 0, 0);
+ parser = message_parser_init(pool, input, &set_empty);
while ((ret = message_parser_parse_next_block(parser, &block)) > 0) ;
test_assert(ret < 0);
message_parser_deinit(&parser, &parts);
static void test_message_part_idx(void)
{
+ const struct message_parser_settings set = { .flags = 0 };
struct message_parser_ctx *parser;
struct istream *input;
struct message_part *parts, *part, *prev_part;
pool = pool_alloconly_create("message parser", 10240);
input = i_stream_create_from_data(test_msg, TEST_MSG_LEN);
- parser = message_parser_init(pool, input, 0, 0);
+ parser = message_parser_init(pool, input, &set);
while ((ret = message_parser_parse_next_block(parser, &block)) > 0) {
part_idx = message_part_to_idx(block.part);
test_assert(part_idx >= prev_idx);
#include "index-storage.h"
#include "index-mail.h"
-static const enum message_header_parser_flags hdr_parser_flags =
- MESSAGE_HEADER_PARSER_FLAG_SKIP_INITIAL_LWSP |
- MESSAGE_HEADER_PARSER_FLAG_DROP_CR;
-static const enum message_parser_flags msg_parser_flags =
- MESSAGE_PARSER_FLAG_SKIP_BODY_BLOCK;
+static const struct message_parser_settings msg_parser_set = {
+ .hdr_flags = MESSAGE_HEADER_PARSER_FLAG_SKIP_INITIAL_LWSP |
+ MESSAGE_HEADER_PARSER_FLAG_DROP_CR,
+ .flags = MESSAGE_PARSER_FLAG_SKIP_BODY_BLOCK,
+};
static int header_line_cmp(const struct index_mail_line *l1,
const struct index_mail_line *l2)
mail->data.parser_input = input;
mail->data.parser_ctx =
message_parser_init(mail->mail.data_pool, input,
- hdr_parser_flags, msg_parser_flags);
+ &msg_parser_set);
i_stream_unref(&input);
return input2;
}
data->parser_input = data->stream;
data->parser_ctx = message_parser_init(mail->mail.data_pool,
data->stream,
- hdr_parser_flags,
- msg_parser_flags);
+ &msg_parser_set);
} else {
data->parser_ctx =
message_parser_init_from_parts(data->parts,
data->stream,
- hdr_parser_flags,
- msg_parser_flags);
+ &msg_parser_set);
}
}
i_assert(!data->save_bodystructure_body ||
data->parser_ctx != NULL);
message_parse_header(data->stream, &data->hdr_size,
- hdr_parser_flags,
+ msg_parser_set.hdr_flags,
index_mail_parse_header_cb, mail);
}
if (index_mail_stream_check_failure(mail) < 0)
if (mail->data.envelope == NULL) {
/* we got the headers from cache - parse them to get the
envelope */
- message_parse_header(stream, NULL, hdr_parser_flags,
+ message_parse_header(stream, NULL, msg_parser_set.hdr_flags,
imap_envelope_parse_callback, mail);
if (stream->stream_errno != 0) {
index_mail_stream_log_failure_for(mail, stream);
const char **retriable_err_msg_r,
bool *may_need_retry_r)
{
+ const struct message_parser_settings parser_set = {
+ .hdr_flags = MESSAGE_HEADER_PARSER_FLAG_CLEAN_ONELINE,
+ };
struct fts_mail_build_context ctx;
struct istream *input;
struct message_parser_ctx *parser;
ctx.pending_input = buffer_create_dynamic(default_pool, 128);
prev_part = NULL;
- parser = message_parser_init(pool_datastack_create(), input,
- MESSAGE_HEADER_PARSER_FLAG_CLEAN_ONELINE,
- 0);
+ parser = message_parser_init(pool_datastack_create(), input, &parser_set);
decoder = message_decoder_init(update_ctx->normalizer, 0);
for (;;) {