Commit 352c5e92 352c5e92e6d26701fccced669c40409d6010ff10 by Sergey Poznyakoff

Bugfixes in stream-related code.

* mailbox/fltstream.c (filter_read): Do not try to get more input until
the output buffer is drained.
* mailbox/mapfile_stream.c (_mapfile_seek): Fix conditional.
* mailbox/stream.c (_stream_fill_buffer): Fix increment.
(mu_stream_skip_input_bytes): Bugfixes.
1 parent 2203753f
...@@ -117,73 +117,78 @@ filter_read (mu_stream_t stream, char *buf, size_t size, size_t *pret) ...@@ -117,73 +117,78 @@ filter_read (mu_stream_t stream, char *buf, size_t size, size_t *pret)
117 117
118 while (total < size && cmd != mu_filter_lastbuf) 118 while (total < size && cmd != mu_filter_lastbuf)
119 { 119 {
120 enum mu_filter_result res;
121 int rc;
122 size_t rdsize; 120 size_t rdsize;
123 121
124 if (MFB_RDBYTES (fs->inbuf) < min_input_level) 122 if (MFB_RDBYTES (fs->outbuf) == 0)
125 { 123 {
126 rc = MFB_require (&fs->inbuf, min_input_level); 124 enum mu_filter_result res;
127 if (rc) 125 int rc;
128 return rc; 126
129 rc = mu_stream_read (fs->transport, 127 if (MFB_RDBYTES (fs->inbuf) < min_input_level)
130 MFB_ENDPTR (fs->inbuf), 128 {
131 MFB_FREESIZE (fs->inbuf), 129 rc = MFB_require (&fs->inbuf, min_input_level);
132 &rdsize); 130 if (rc)
131 return rc;
132 rc = mu_stream_read (fs->transport,
133 MFB_ENDPTR (fs->inbuf),
134 MFB_FREESIZE (fs->inbuf),
135 &rdsize);
136 if (rc)
137 return rc;
138 if (rdsize == 0 &&
139 MFB_RDBYTES (fs->outbuf) == 0
140 && MFB_RDBYTES (fs->inbuf) == 0)
141 break;
142 MFB_advance_level (&fs->inbuf, rdsize);
143 }
144
145 if (min_output_size < MFB_RDBYTES (fs->inbuf))
146 min_output_size = MFB_RDBYTES (fs->inbuf);
147 rc = MFB_require (&fs->outbuf, min_output_size);
133 if (rc) 148 if (rc)
134 return rc; 149 return rc;
135 if (rdsize == 0 &&
136 MFB_RDBYTES (fs->outbuf) == 0 && MFB_RDBYTES (fs->inbuf) == 0)
137 break;
138 MFB_advance_level (&fs->inbuf, rdsize);
139 }
140
141 if (min_output_size < MFB_RDBYTES (fs->inbuf))
142 min_output_size = MFB_RDBYTES (fs->inbuf);
143 rc = MFB_require (&fs->outbuf, min_output_size);
144 if (rc)
145 return rc;
146 150
147 init_iobuf (&iobuf, fs); 151 init_iobuf (&iobuf, fs);
148 152
149 cmd = mu_stream_eof (fs->transport) ? 153 cmd = mu_stream_eof (fs->transport) ?
150 mu_filter_lastbuf : mu_filter_xcode; 154 mu_filter_lastbuf : mu_filter_xcode;
151 res = fs->xcode (fs->xdata, cmd, &iobuf); 155 res = fs->xcode (fs->xdata, cmd, &iobuf);
152 switch (res) 156 switch (res)
153 {
154 case mu_filter_ok:
155 if (iobuf.isize == 0 || iobuf.osize == 0)
156 { 157 {
157 /* FIXME: Hack to handle eventual buggy filters */ 158 case mu_filter_ok:
158 if (iobuf.isize == 0) 159 if (iobuf.isize == 0 || iobuf.osize == 0)
159 min_input_level++; 160 {
160 if (iobuf.osize == 0) 161 /* FIXME: Hack to handle eventual buggy filters */
161 min_output_size++; 162 if (iobuf.isize == 0)
163 min_input_level++;
164 if (iobuf.osize == 0)
165 min_output_size++;
166 continue;
167 }
168 if (iobuf.isize > MFB_RDBYTES (fs->inbuf)
169 || iobuf.osize > MFB_FREESIZE (fs->outbuf))
170 return MU_ERR_FAILURE; /* FIXME: special error code? */
171 break;
172
173 case mu_filter_falure:
174 return iobuf.errcode;
175
176 case mu_filter_moreinput:
177 min_input_level = iobuf.isize;
178 continue;
179
180 case mu_filter_moreoutput:
181 min_output_size = iobuf.osize;
162 continue; 182 continue;
163 } 183 }
164 if (iobuf.isize > MFB_RDBYTES (fs->inbuf) 184
165 || iobuf.osize > MFB_FREESIZE (fs->outbuf)) 185 /* iobuf.osize contains number of bytes written to output */
166 return MU_ERR_FAILURE; /* FIXME: special error code? */ 186 MFB_advance_level (&fs->outbuf, iobuf.osize);
167 break;
168
169 case mu_filter_falure:
170 return iobuf.errcode;
171
172 case mu_filter_moreinput:
173 min_input_level = iobuf.isize;
174 continue;
175 187
176 case mu_filter_moreoutput: 188 /* iobuf.isize contains number of bytes read from input */
177 min_output_size = iobuf.osize; 189 MFB_advance_pos (&fs->inbuf, iobuf.isize);
178 continue;
179 } 190 }
180 191
181 /* iobuf.osize contains number of bytes written to output */
182 MFB_advance_level (&fs->outbuf, iobuf.osize);
183
184 /* iobuf.isize contains number of bytes read from input */
185 MFB_advance_pos (&fs->inbuf, iobuf.isize);
186
187 rdsize = size - total; 192 rdsize = size - total;
188 if (rdsize > MFB_RDBYTES (fs->outbuf)) 193 if (rdsize > MFB_RDBYTES (fs->outbuf))
189 rdsize = MFB_RDBYTES (fs->outbuf); 194 rdsize = MFB_RDBYTES (fs->outbuf);
......
...@@ -316,7 +316,7 @@ _mapfile_seek (struct _mu_stream *str, mu_off_t off, mu_off_t *presult) ...@@ -316,7 +316,7 @@ _mapfile_seek (struct _mu_stream *str, mu_off_t off, mu_off_t *presult)
316 { 316 {
317 struct _mu_mapfile_stream *mfs = (struct _mu_mapfile_stream *) str; 317 struct _mu_mapfile_stream *mfs = (struct _mu_mapfile_stream *) str;
318 318
319 if (off < 0 || off >= mfs->size) 319 if (off < 0 || off > mfs->size)
320 return ESPIPE; 320 return ESPIPE;
321 mfs->offset = off; 321 mfs->offset = off;
322 *presult = off; 322 *presult = off;
......
...@@ -80,9 +80,9 @@ _stream_fill_buffer (struct _mu_stream *stream) ...@@ -80,9 +80,9 @@ _stream_fill_buffer (struct _mu_stream *stream)
80 n < stream->bufsize 80 n < stream->bufsize
81 && (rc = mu_stream_read_unbuffered (stream, 81 && (rc = mu_stream_read_unbuffered (stream,
82 &c, 1, 0, &rdn)) == 0 82 &c, 1, 0, &rdn)) == 0
83 && rdn; n++) 83 && rdn; )
84 { 84 {
85 stream->buffer[n] = c; 85 stream->buffer[n++] = c;
86 if (c == '\n') 86 if (c == '\n')
87 break; 87 break;
88 } 88 }
...@@ -368,10 +368,10 @@ mu_stream_skip_input_bytes (mu_stream_t stream, mu_off_t count, mu_off_t *pres) ...@@ -368,10 +368,10 @@ mu_stream_skip_input_bytes (mu_stream_t stream, mu_off_t count, mu_off_t *pres)
368 } 368 }
369 else 369 else
370 { 370 {
371 if ((rc = _stream_flush_buffer (stream, 1)))
372 return rc;
373 for (pos = 0;;) 371 for (pos = 0;;)
374 { 372 {
373 if ((rc = _stream_flush_buffer (stream, 1)))
374 return rc;
375 if (stream->level == 0) 375 if (stream->level == 0)
376 { 376 {
377 rc = _stream_fill_buffer (stream); 377 rc = _stream_fill_buffer (stream);
...@@ -385,11 +385,13 @@ mu_stream_skip_input_bytes (mu_stream_t stream, mu_off_t count, mu_off_t *pres) ...@@ -385,11 +385,13 @@ mu_stream_skip_input_bytes (mu_stream_t stream, mu_off_t count, mu_off_t *pres)
385 } 385 }
386 if (pos <= count && count < pos + stream->level) 386 if (pos <= count && count < pos + stream->level)
387 { 387 {
388 rc = 0; 388 size_t delta = count - pos;
389 stream->cur = stream->buffer + count - pos; 389 _stream_advance_buffer (stream, delta);
390 pos = count; 390 pos = count;
391 rc = 0;
391 break; 392 break;
392 } 393 }
394 pos += stream->level;
393 } 395 }
394 } 396 }
395 397
......