dovecot-2.2: fts-tika: Fixed crashes when indexing larger attach...
dovecot at dovecot.org
dovecot at dovecot.org
Wed Jun 17 10:15:24 UTC 2015
details: http://hg.dovecot.org/dovecot-2.2/rev/3ae8cf3f8320
changeset: 18875:3ae8cf3f8320
user: Timo Sirainen <tss at iki.fi>
date: Wed Jun 17 13:12:37 2015 +0300
description:
fts-tika: Fixed crashes when indexing larger attachments with fts-solr.
We were mixing ioloops without switching back to the original ioloop in the
middle. Also io_remove() at deinit caused another timeout to be added, so
this needs to be done while original ioloop is active or we'll just leak the
just-added timeout in io_loop_destroy() and crash later.
diffstat:
src/plugins/fts/fts-parser-tika.c | 29 +++++++++++++++++++----------
1 files changed, 19 insertions(+), 10 deletions(-)
diffs (65 lines):
diff -r 343602625064 -r 3ae8cf3f8320 src/plugins/fts/fts-parser-tika.c
--- a/src/plugins/fts/fts-parser-tika.c Wed Jun 17 12:22:17 2015 +0300
+++ b/src/plugins/fts/fts-parser-tika.c Wed Jun 17 13:12:37 2015 +0300
@@ -148,6 +148,7 @@
struct message_block *block)
{
struct tika_fts_parser *parser = (struct tika_fts_parser *)_parser;
+ struct ioloop *prev_ioloop = current_ioloop;
const unsigned char *data;
size_t size;
ssize_t ret;
@@ -174,10 +175,11 @@
return;
i_assert(parser->payload != NULL);
}
- /* continue returning data from Tika */
+ /* continue returning data from Tika. we'll create a new ioloop just
+ for reading this one payload. */
while ((ret = i_stream_read_data(parser->payload, &data, &size, 0)) == 0) {
if (parser->failed)
- return;
+ break;
/* wait for more input from Tika */
if (parser->ioloop == NULL) {
parser->ioloop = io_loop_create();
@@ -188,7 +190,12 @@
}
io_loop_run(current_ioloop);
}
- if (size > 0) {
+ /* switch back to original ioloop. */
+ io_loop_set_current(prev_ioloop);
+
+ if (parser->failed)
+ ;
+ else if (size > 0) {
i_assert(ret > 0);
block->data = data;
block->size = size;
@@ -210,16 +217,18 @@
struct tika_fts_parser *parser = (struct tika_fts_parser *)_parser;
int ret = parser->failed ? -1 : 0;
+ /* remove io before unrefing payload - otherwise lib-http adds another
+ timeout to ioloop unnecessarily */
+ if (parser->payload != NULL)
+ i_stream_unref(&parser->payload);
+ if (parser->io != NULL)
+ io_remove(&parser->io);
+ if (parser->http_req != NULL)
+ http_client_request_abort(&parser->http_req);
if (parser->ioloop != NULL) {
- io_remove(&parser->io);
+ io_loop_set_current(parser->ioloop);
io_loop_destroy(&parser->ioloop);
}
- if (parser->payload != NULL)
- i_stream_unref(&parser->payload);
- /* FIXME: kludgy, http_req should be NULL here if we don't want to
- free it. requires lib-http changes. */
- if (parser->http_req != NULL)
- http_client_request_abort(&parser->http_req);
i_free(parser);
return ret;
}
More information about the dovecot-cvs
mailing list