annotate src/lib/istream-base64-decoder.c @ 22664:fea53c2725c0

director: Fix director_max_parallel_moves/kicks type Should be uint, not time.
author Timo Sirainen <timo.sirainen@dovecot.fi>
date Thu, 09 Nov 2017 12:24:16 +0200
parents 2e2563132d5f
children cb108f786fb4
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
21390
2e2563132d5f Updated copyright notices to include the year 2017.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents: 19552
diff changeset
1 /* Copyright (c) 2013-2017 Dovecot authors, see the included COPYING file */
14845
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
2
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
3 #include "lib.h"
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
4 #include "buffer.h"
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
5 #include "base64.h"
16773
76d5e3c8cec3 iostreams: Set stream error string when it provides extra information.
Timo Sirainen <tss@iki.fi>
parents: 15715
diff changeset
6 #include "hex-binary.h"
14845
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
7 #include "istream-private.h"
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
8 #include "istream-base64.h"
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
9
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
10 struct base64_decoder_istream {
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
11 struct istream_private istream;
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
12 };
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
13
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
14 static int i_stream_read_parent(struct istream_private *stream)
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
15 {
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
16 size_t size;
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
17 ssize_t ret;
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
18
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
19 size = i_stream_get_data_size(stream->parent);
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
20 if (size >= 4)
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
21 return 1;
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
22
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
23 /* we have less than one base64 block.
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
24 see if there is more data available. */
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
25 ret = i_stream_read(stream->parent);
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
26 if (ret <= 0) {
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
27 stream->istream.stream_errno = stream->parent->stream_errno;
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
28 stream->istream.eof = stream->parent->eof;
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
29 return ret;
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
30 }
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
31 size = i_stream_get_data_size(stream->parent);
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
32 i_assert(size != 0);
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
33 return 1;
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
34 }
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
35
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
36 static int
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
37 i_stream_base64_try_decode_block(struct base64_decoder_istream *bstream)
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
38 {
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
39 struct istream_private *stream = &bstream->istream;
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
40 const unsigned char *data;
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
41 size_t size, avail, buffer_avail, pos;
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
42 buffer_t buf;
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
43
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
44 data = i_stream_get_data(stream->parent, &size);
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
45 if (size == 0)
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
46 return 0;
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
47
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
48 i_stream_try_alloc(stream, (size+3)/4*3, &avail);
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
49 buffer_avail = stream->buffer_size - stream->pos;
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
50
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
51 if ((size + 3) / 4 * 3 > buffer_avail) {
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
52 /* can't fit everything to destination buffer.
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
53 write as much as we can. */
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
54 size = (buffer_avail / 3) * 4;
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
55 if (size == 0)
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
56 return -2;
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
57 }
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
58
15034
7efef678bca8 Renamed buffer_create_*data() to buffer_create_from_*data() for consistency.
Timo Sirainen <tss@iki.fi>
parents: 14948
diff changeset
59 buffer_create_from_data(&buf, stream->w_buffer + stream->pos,
7efef678bca8 Renamed buffer_create_*data() to buffer_create_from_*data() for consistency.
Timo Sirainen <tss@iki.fi>
parents: 14948
diff changeset
60 buffer_avail);
14845
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
61 if (base64_decode(data, size, &pos, &buf) < 0) {
16773
76d5e3c8cec3 iostreams: Set stream error string when it provides extra information.
Timo Sirainen <tss@iki.fi>
parents: 15715
diff changeset
62 io_stream_set_error(&stream->iostream,
76d5e3c8cec3 iostreams: Set stream error string when it provides extra information.
Timo Sirainen <tss@iki.fi>
parents: 15715
diff changeset
63 "Invalid base64 data: 0x%s",
17506
c65b4c41698c lib: Fixed read buffer overflow in istream-base64-decoder error handling
Timo Sirainen <tss@iki.fi>
parents: 17130
diff changeset
64 binary_to_hex(data+pos, I_MIN(size-pos, 8)));
14845
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
65 stream->istream.stream_errno = EINVAL;
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
66 return -1;
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
67 }
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
68
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
69 stream->pos += buf.used;
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
70 i_stream_skip(stream->parent, pos);
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
71 return pos > 0 ? 1 : 0;
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
72 }
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
73
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
74 static ssize_t i_stream_base64_decoder_read(struct istream_private *stream)
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
75 {
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
76 struct base64_decoder_istream *bstream =
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
77 (struct base64_decoder_istream *)stream;
16773
76d5e3c8cec3 iostreams: Set stream error string when it provides extra information.
Timo Sirainen <tss@iki.fi>
parents: 15715
diff changeset
78 const unsigned char *data;
76d5e3c8cec3 iostreams: Set stream error string when it provides extra information.
Timo Sirainen <tss@iki.fi>
parents: 15715
diff changeset
79 size_t pre_count, post_count, size;
14845
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
80 int ret;
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
81
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
82 do {
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
83 ret = i_stream_read_parent(stream);
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
84 if (ret <= 0) {
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
85 if (ret < 0 && stream->istream.stream_errno == 0 &&
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
86 i_stream_get_data_size(stream->parent) > 0) {
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
87 /* base64 input with a partial block */
16773
76d5e3c8cec3 iostreams: Set stream error string when it provides extra information.
Timo Sirainen <tss@iki.fi>
parents: 15715
diff changeset
88 data = i_stream_get_data(stream->parent, &size);
76d5e3c8cec3 iostreams: Set stream error string when it provides extra information.
Timo Sirainen <tss@iki.fi>
parents: 15715
diff changeset
89 io_stream_set_error(&stream->iostream,
76d5e3c8cec3 iostreams: Set stream error string when it provides extra information.
Timo Sirainen <tss@iki.fi>
parents: 15715
diff changeset
90 "base64 input ends with a partial block: 0x%s",
76d5e3c8cec3 iostreams: Set stream error string when it provides extra information.
Timo Sirainen <tss@iki.fi>
parents: 15715
diff changeset
91 binary_to_hex(data, size));
14845
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
92 stream->istream.stream_errno = EINVAL;
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
93 }
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
94 return ret;
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
95 }
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
96
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
97 /* encode as many blocks as fits into destination buffer */
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
98 pre_count = stream->pos - stream->skip;
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
99 while ((ret = i_stream_base64_try_decode_block(bstream)) > 0) ;
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
100 post_count = stream->pos - stream->skip;
14846
4d13da5c571b Various fixes to istream-base64-encoder/decoder
Timo Sirainen <tss@iki.fi>
parents: 14845
diff changeset
101 } while (ret == 0 && pre_count == post_count);
14845
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
102
14948
5cf1cedb75e6 istream-base64: Fixed returning -2 too early.
Timo Sirainen <tss@iki.fi>
parents: 14846
diff changeset
103 if (ret < 0 && pre_count == post_count)
14845
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
104 return ret;
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
105
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
106 i_assert(post_count > pre_count);
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
107 return post_count - pre_count;
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
108 }
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
109
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
110 static void
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
111 i_stream_base64_decoder_seek(struct istream_private *stream,
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
112 uoff_t v_offset, bool mark)
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
113 {
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
114 if (v_offset < stream->istream.v_offset) {
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
115 /* seeking backwards - go back to beginning and seek
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
116 forward from there. */
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
117 stream->parent_expected_offset = stream->parent_start_offset;
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
118 stream->skip = stream->pos = 0;
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
119 stream->istream.v_offset = 0;
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
120 i_stream_seek(stream->parent, 0);
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
121 }
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
122 i_stream_default_seek_nonseekable(stream, v_offset, mark);
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
123 }
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
124
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
125 struct istream *
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
126 i_stream_create_base64_decoder(struct istream *input)
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
127 {
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
128 struct base64_decoder_istream *bstream;
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
129
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
130 bstream = i_new(struct base64_decoder_istream, 1);
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
131 bstream->istream.max_buffer_size = input->real_stream->max_buffer_size;
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
132
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
133 bstream->istream.read = i_stream_base64_decoder_read;
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
134 bstream->istream.seek = i_stream_base64_decoder_seek;
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
135
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
136 bstream->istream.istream.readable_fd = FALSE;
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
137 bstream->istream.istream.blocking = input->blocking;
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
138 bstream->istream.istream.seekable = input->seekable;
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
139 return i_stream_create(&bstream->istream, input,
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
140 i_stream_get_fd(input));
39b1b519c033 Added istream-base64-decoder.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
141 }