static ssize_t i_stream_qp_decoder_read(struct istream_private *stream)
{
    struct qp_decoder_istream *bstream =
        (struct qp_decoder_istream *)stream;
    const unsigned char *data;
    size_t pre_count, post_count, size;
    int ret;
    size_t prev_size = 0;

    do {
        ret = i_stream_read_parent(stream, &prev_size);
        if (ret <= 0) {
            if (ret != -1 || stream->istream.stream_errno != 0)
                return 0;

            ret = i_stream_qp_try_decode_input(bstream, TRUE);
            if (ret == 0) {
                /* ended with =[whitespace] but without LF */
                stream->istream.eof = TRUE;
                return -1;
            }
            /* partial qp input */
            i_assert(ret < 0);
            data = i_stream_get_data(stream->parent, &size);
            io_stream_set_error(&stream->iostream,
                                "quoted-printable input ends with a partial block: 0x%s",
                                binary_to_hex(data, size));
            stream->istream.stream_errno = EINVAL;
            return -1;
        }

        /* encode as much data as fits into destination buffer */
        pre_count = stream->pos - stream->skip;
        while ((ret = i_stream_qp_try_decode_input(bstream, FALSE)) > 0) ;
        post_count = stream->pos - stream->skip;
    } while (ret == 0 && pre_count == post_count);

    if (ret < 0)
        return ret;

    i_assert(post_count > pre_count);
    return post_count - pre_count;
}
Ejemplo n.º 2
0
static ssize_t i_stream_qp_decoder_read(struct istream_private *stream)
{
	struct qp_decoder_istream *bstream =
		(struct qp_decoder_istream *)stream;
	size_t pre_count, post_count;
	int ret;
	size_t prev_size = 0;

	do {
		ret = i_stream_read_parent(stream, &prev_size);
		if (ret <= 0) {
			if (ret != -1 || stream->istream.stream_errno != 0)
				return 0;

			ret = i_stream_qp_try_decode_input(bstream, TRUE);
			if (ret == 0) {
				/* ended with =[whitespace] but without LF */
				stream->istream.eof = TRUE;
				return -1;
			}
			/* partial qp input */
			i_assert(ret < 0);
			stream->istream.stream_errno = EINVAL;
			return -1;
		}

		/* encode as much data as fits into destination buffer */
		pre_count = stream->pos - stream->skip;
		while ((ret = i_stream_qp_try_decode_input(bstream, FALSE)) > 0) ;
		post_count = stream->pos - stream->skip;
	} while (ret == 0 && pre_count == post_count);

	if (ret < 0)
		return ret;

	i_assert(post_count > pre_count);
	return post_count - pre_count;
}