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