/* Copyright (c) 2013-2018 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "buffer.h"
#include "base64.h"
#include "istream-private.h"
#include "message-parser.h"
#include "istream-binary-converter.h"
struct binary_converter_istream {
unsigned int base64_delayed_len;
unsigned int base64_block_pos;
};
{
/* some MUAs use "c-t-e: binary" for multiparts.
we don't want to convert them. */
}
static void
{
const unsigned char *data;
} else {
"Content-Transfer-Encoding: base64\r\n", 35);
}
buffer_free(&buf);
}
{
if (size == 0)
return;
return;
}
/* buffer is getting too large. just finish the decision. */
}
}
{
void *dest;
if (bstream->base64_delayed_len > 0) {
return;
}
if (size == 0) {
/* finish base64 */
} else {
data, missing_len);
data += missing_len;
size -= missing_len;
}
bstream->base64_block_pos = 0;
}
bstream->base64_delayed_len = 0;
}
while (size >= BASE64_BLOCK_INPUT_SIZE) {
bstream->base64_block_pos = 0;
}
/* try to encode one full line of base64 blocks */
if (encode_size % BASE64_BLOCK_INPUT_SIZE != 0)
}
data += encode_size;
size -= encode_size;
}
if (size > 0) {
/* encode these when more data is available */
}
}
const struct message_header_line *hdr)
{
}
if (!hdr->no_newline)
}
{
/* @UNSAFE */
(struct binary_converter_istream *)stream;
return -2;
case -1:
/* done / error */
bstream->base64_delayed_len > 0) {
/* flush any pending base64 output */
}
return -1;
case 0:
/* need more data */
return 0;
default:
break;
}
/* end of base64 encoded part */
}
/* parsing a header */
/* looks like we want to convert this body part to
base64, but if we haven't seen Content-Type yet
delay the decision until we've read the rest of
the header */
bstream->base64_block_pos = 0;
if (!bstream->content_type_seen) {
} else {
"Content-Transfer-Encoding: base64\r\n", 35);
}
/* finish the decision about decoding */
} else {
}
/* end of header */
/* message has no body */
}
/* convert body part to base64 */
} else {
}
return i_stream_binary_converter_read(stream);
}
bool close_parent)
{
(struct binary_converter_istream *)stream;
}
if (close_parent)
}
{
i_stream_get_fd(input), 0);
}