}
}
-static int astream_decode_base64(struct attachment_istream *astream)
+static int astream_decode_base64(struct attachment_istream *astream,
+ buffer_t **extra_buf_r)
{
struct attachment_istream_part *part = &astream->part;
- buffer_t *extra_buf = NULL;
struct istream *input, *base64_input;
struct ostream *output;
const unsigned char *data;
int outfd;
bool failed = FALSE;
+ *extra_buf_r = NULL;
+
if (part->base64_bytes < astream->set.min_size ||
part->temp_output->offset > part->base64_bytes +
BASE64_ATTACHMENT_MAX_EXTRA_BYTES) {
if (input->v_offset != part->temp_output->offset && !failed) {
/* write the rest of the data to the message stream */
- extra_buf = buffer_create_dynamic(default_pool, 1024);
+ *extra_buf_r = buffer_create_dynamic(default_pool, 1024);
while ((ret = i_stream_read_more(input, &data, &size)) > 0) {
- buffer_append(extra_buf, data, size);
+ buffer_append(*extra_buf_r, data, size);
i_stream_skip(input, size);
}
i_assert(ret == -1);
o_stream_destroy(&part->temp_output);
i_close_fd(&part->temp_fd);
part->temp_fd = outfd;
-
- if (extra_buf != NULL) {
- stream_add_data(astream, extra_buf->data, extra_buf->used);
- buffer_free(&extra_buf);
- }
return 0;
}
struct istream *input;
struct ostream *output;
string_t *digest_str;
+ buffer_t *extra_buf = NULL;
const unsigned char *data;
size_t size;
int ret = 0;
}
if (part->base64_state == BASE64_STATE_EOM) {
/* base64 data looks ok. */
- if (astream_decode_base64(astream) < 0)
+ if (astream_decode_base64(astream, &extra_buf) < 0)
part->base64_failed = TRUE;
} else {
part->base64_failed = TRUE;
info.encoded_size = part->temp_output->offset;
}
if (astream->set.open_attachment_ostream(&info, &output, error_r,
- astream->context) < 0)
+ astream->context) < 0) {
+ buffer_free(&extra_buf);
return -1;
+ }
/* copy data to attachment from temp file */
input = i_stream_create_fd(part->temp_fd, IO_BLOCK_SIZE);
if (astream->set.close_attachment_ostream(output, ret == 0, error_r,
astream->context) < 0)
ret = -1;
+ if (ret == 0 && extra_buf != NULL)
+ stream_add_data(astream, extra_buf->data, extra_buf->used);
+ buffer_free(&extra_buf);
return ret;
}