filter stream: make sure all input data get processed.
* include/mailutils/filter.h (MU_FILTER_MAX_AGAIN): Add a comment. * libmailutils/stream/fltstream.c (filter_read): Use mu_debug on the filter.error level, instead of plain mu_error. If the xcoder returns OK and does not consume all input when processing the last buffer, assume mu_filter_again. Fix loop condition. (filter_write_internal): Use mu_debug on the filter.error level, instead of plain mu_error.
Showing
2 changed files
with
38 additions
and
9 deletions
... | @@ -62,6 +62,8 @@ enum mu_filter_result | ... | @@ -62,6 +62,8 @@ enum mu_filter_result |
62 | mu_filter_again | 62 | mu_filter_again |
63 | }; | 63 | }; |
64 | 64 | ||
65 | /* An xcode function is not allowed to return mu_filter_again more | ||
66 | than MU_FILTER_MAX_AGAIN times in a sequence. */ | ||
65 | #define MU_FILTER_MAX_AGAIN 5 | 67 | #define MU_FILTER_MAX_AGAIN 5 |
66 | 68 | ||
67 | typedef int (*mu_filter_new_data_t) (void **, int, int argc, | 69 | typedef int (*mu_filter_new_data_t) (void **, int, int argc, | ... | ... |
... | @@ -172,18 +172,13 @@ filter_read (mu_stream_t stream, char *buf, size_t size, size_t *pret) | ... | @@ -172,18 +172,13 @@ filter_read (mu_stream_t stream, char *buf, size_t size, size_t *pret) |
172 | if (++again > MU_FILTER_MAX_AGAIN) | 172 | if (++again > MU_FILTER_MAX_AGAIN) |
173 | { | 173 | { |
174 | /* FIXME: What filter? Need some id. */ | 174 | /* FIXME: What filter? Need some id. */ |
175 | mu_error (_("filter returned `again' too many times")); | 175 | mu_debug (MU_DEBCAT_FILTER, MU_DEBUG_ERROR, |
176 | (_("filter returned `again' too many times"))); | ||
176 | again = 0; | 177 | again = 0; |
177 | } | 178 | } |
178 | break; | 179 | break; |
179 | 180 | ||
180 | case mu_filter_ok: | 181 | case mu_filter_ok: |
181 | again = 0; | ||
182 | if (cmd == mu_filter_lastbuf || iobuf.eof) | ||
183 | { | ||
184 | fs->fltflag |= _MU_FILTER_EOF; | ||
185 | stop = 1; | ||
186 | } | ||
187 | break; | 182 | break; |
188 | 183 | ||
189 | case mu_filter_failure: | 184 | case mu_filter_failure: |
... | @@ -207,6 +202,37 @@ filter_read (mu_stream_t stream, char *buf, size_t size, size_t *pret) | ... | @@ -207,6 +202,37 @@ filter_read (mu_stream_t stream, char *buf, size_t size, size_t *pret) |
207 | 202 | ||
208 | /* iobuf.isize contains number of bytes read from input */ | 203 | /* iobuf.isize contains number of bytes read from input */ |
209 | MFB_advance_pos (&fs->inbuf, iobuf.isize); | 204 | MFB_advance_pos (&fs->inbuf, iobuf.isize); |
205 | |||
206 | if (res == mu_filter_ok) | ||
207 | { | ||
208 | if (iobuf.eof) | ||
209 | { | ||
210 | fs->fltflag |= _MU_FILTER_EOF; | ||
211 | stop = 1; | ||
212 | } | ||
213 | else if (cmd == mu_filter_lastbuf) | ||
214 | { | ||
215 | if (MFB_RDBYTES (fs->inbuf)) | ||
216 | { | ||
217 | /* If xcoder has not consumed all input, try again */ | ||
218 | if (++again > MU_FILTER_MAX_AGAIN) | ||
219 | { | ||
220 | /* FIXME: What filter? Need some id. */ | ||
221 | mu_debug (MU_DEBCAT_FILTER, MU_DEBUG_ERROR, | ||
222 | (_("filter returned `again' too many times"))); | ||
223 | stop = 1; | ||
224 | } | ||
225 | } | ||
226 | |||
227 | else | ||
228 | { | ||
229 | fs->fltflag |= _MU_FILTER_EOF; | ||
230 | stop = 1; | ||
231 | } | ||
232 | } | ||
233 | else | ||
234 | again = 0; | ||
235 | } | ||
210 | } | 236 | } |
211 | 237 | ||
212 | rdsize = size - total; | 238 | rdsize = size - total; |
... | @@ -217,7 +243,7 @@ filter_read (mu_stream_t stream, char *buf, size_t size, size_t *pret) | ... | @@ -217,7 +243,7 @@ filter_read (mu_stream_t stream, char *buf, size_t size, size_t *pret) |
217 | total += rdsize; | 243 | total += rdsize; |
218 | 244 | ||
219 | } | 245 | } |
220 | while (!stop && (total < size || again)); | 246 | while (!stop && total < size); |
221 | 247 | ||
222 | *pret = total; | 248 | *pret = total; |
223 | return 0; | 249 | return 0; |
... | @@ -278,7 +304,8 @@ filter_write_internal (mu_stream_t stream, enum mu_filter_command cmd, | ... | @@ -278,7 +304,8 @@ filter_write_internal (mu_stream_t stream, enum mu_filter_command cmd, |
278 | if (++again > MU_FILTER_MAX_AGAIN) | 304 | if (++again > MU_FILTER_MAX_AGAIN) |
279 | { | 305 | { |
280 | /* FIXME: What filter? Need some id. */ | 306 | /* FIXME: What filter? Need some id. */ |
281 | mu_error (_("filter returned `again' too many times")); | 307 | mu_debug (MU_DEBCAT_FILTER, MU_DEBUG_ERROR, |
308 | (_("filter returned `again' too many times"))); | ||
282 | again = 0; | 309 | again = 0; |
283 | } | 310 | } |
284 | break; | 311 | break; | ... | ... |
-
Please register or sign in to post a comment