message-decoder.c revision 01eef06269e04d0b1b6d67c5055248fefb4f613e
/* Copyright (c) 2006-2015 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "buffer.h"
#include "base64.h"
#include "str.h"
#include "unichar.h"
#include "charset-utf8.h"
#include "quoted-printable.h"
#include "rfc822-parser.h"
#include "rfc2231-parser.h"
#include "message-parser.h"
#include "message-header-decode.h"
#include "message-decoder.h"
/* base64 takes max 4 bytes per character, q-p takes max 3. */
#define MAX_ENCODING_BUF_SIZE 3
struct message_decoder_context {
enum message_decoder_flags flags;
struct message_part *prev_part;
struct message_header_line hdr;
char *charset_trans_charset;
struct charset_translation *charset_trans;
unsigned int translation_size;
char *content_type, *content_charset;
enum message_cte message_cte;
unsigned int binary_input:1;
};
static void
struct message_part *part);
struct message_decoder_context *
enum message_decoder_flags flags)
{
struct message_decoder_context *ctx;
return ctx;
}
{
}
bool set)
{
if (set)
else
}
{
struct rfc822_parser_context parser;
enum message_cte message_cte;
case 4:
break;
case 6:
break;
case 16:
break;
}
return message_cte;
}
static void
struct message_header_line *hdr)
{
struct rfc822_parser_context parser;
const char *const *results;
return;
return;
break;
}
}
}
struct message_header_line *hdr,
struct message_block *output)
{
return FALSE;
}
T_BEGIN {
} T_END;
} else {
}
}
return TRUE;
}
{
unsigned int data_wanted, skip;
/* @UNSAFE: move the previously untranslated bytes to trans_buf
and see if we have now enough data to get the next character
translated */
if (data_wanted > *size)
data_wanted = *size;
/* need more data to finish the translation. */
*size = 0;
return;
}
ctx->translation_size = 0;
}
static void
struct message_part *part)
{
MESSAGE_PART_FLAG_MESSAGE_RFC822)) == 0;
if (ctx->binary_input)
return;
/* already have the correct translation selected */
return;
}
&ctx->charset_trans) < 0)
}
struct message_block *input,
struct message_block *output)
{
int ret;
/* @UNSAFE */
}
switch (ctx->message_cte) {
case MESSAGE_CTE_UNKNOWN:
/* just skip this body */
return FALSE;
case MESSAGE_CTE_78BIT:
case MESSAGE_CTE_BINARY:
break;
case MESSAGE_CTE_QP:
} else {
}
break;
case MESSAGE_CTE_BASE64:
} else {
}
if (ret < 0) {
/* corrupted base64 data, don't bother with
the rest of it */
return FALSE;
}
if (ret == 0) {
/* end of base64 input */
}
break;
}
}
if (ctx->binary_input) {
} else {
if (ctx->translation_size != 0)
sizeof(ctx->translation_buf));
}
}
return TRUE;
}
struct message_block *input,
struct message_block *output)
{
/* MIME part changed. */
}
else {
return TRUE;
}
}
const char *
{
return ctx->content_type;
}
{
}