From c751d077967cac45fb427aad1b156cd7dfd62492 Mon Sep 17 00:00:00 2001
From: Stephan Bosch <stephan@rename-it.nl>
Date: Sun, 29 Nov 2015 21:33:33 +0100
Subject: [PATCH] lib-sieve: Fixed memory leak in code dumper. The free handler
 of code dumper extensions was never executed.

---
 .../plugins/variables/ext-variables-dump.c    |  6 ++++--
 src/lib-sieve/sieve-code-dumper.c             | 19 +++++++++++++++----
 src/lib-sieve/sieve-code-dumper.h             |  2 +-
 3 files changed, 20 insertions(+), 7 deletions(-)

diff --git a/src/lib-sieve/plugins/variables/ext-variables-dump.c b/src/lib-sieve/plugins/variables/ext-variables-dump.c
index b574ea38b..25cf5be8e 100644
--- a/src/lib-sieve/plugins/variables/ext-variables-dump.c
+++ b/src/lib-sieve/plugins/variables/ext-variables-dump.c
@@ -19,7 +19,8 @@
 static void ext_variables_code_dumper_free
 	(struct sieve_code_dumper *dumper, void *context);
 
-const struct sieve_code_dumper_extension variables_dump_extension = {
+static const struct sieve_code_dumper_extension
+variables_dump_extension = {
 	&variables_extension,
 	ext_variables_code_dumper_free
 };
@@ -62,7 +63,8 @@ static struct ext_variables_dump_context *ext_variables_dump_get_context
 		p_array_init(&dctx->ext_scopes, pool,
 			sieve_extensions_get_count(this_ext->svinst));
 
-		sieve_dump_extension_set_context(dumper, this_ext, dctx);
+		sieve_dump_extension_register
+			(dumper, this_ext, &variables_dump_extension, dctx);
 	}
 
 	return dctx;
diff --git a/src/lib-sieve/sieve-code-dumper.c b/src/lib-sieve/sieve-code-dumper.c
index a07d4c79b..de444169c 100644
--- a/src/lib-sieve/sieve-code-dumper.c
+++ b/src/lib-sieve/sieve-code-dumper.c
@@ -67,12 +67,23 @@ struct sieve_code_dumper *sieve_code_dumper_create
 	return cdumper;
 }
 
-void sieve_code_dumper_free(struct sieve_code_dumper **cdumper)
+void sieve_code_dumper_free(struct sieve_code_dumper **_cdumper)
 {
-	sieve_binary_debug_reader_deinit(&(*cdumper)->dreader);
+	struct sieve_code_dumper *cdumper = *_cdumper;
+	const struct sieve_code_dumper_extension_reg *eregs;
+	unsigned int count, i;
 
-	pool_unref(&((*cdumper)->pool));
-	*cdumper = NULL;
+	sieve_binary_debug_reader_deinit(&cdumper->dreader);
+
+	/* Signal registered extensions that the dumper is being destroyed */
+	eregs = array_get(&cdumper->extensions, &count);
+	for ( i = 0; i < count; i++ ) {
+		if ( eregs[i].cdmpext != NULL && eregs[i].cdmpext->free != NULL )
+			eregs[i].cdmpext->free(cdumper, eregs[i].context);
+	}
+
+	pool_unref(&cdumper->pool);
+	*_cdumper = NULL;
 }
 
 pool_t sieve_code_dumper_pool(struct sieve_code_dumper *cdumper)
diff --git a/src/lib-sieve/sieve-code-dumper.h b/src/lib-sieve/sieve-code-dumper.h
index 4070e09a5..05d0bc812 100644
--- a/src/lib-sieve/sieve-code-dumper.h
+++ b/src/lib-sieve/sieve-code-dumper.h
@@ -11,7 +11,7 @@ struct sieve_code_dumper;
 struct sieve_code_dumper *sieve_code_dumper_create
 	(struct sieve_dumptime_env *denv);
 void sieve_code_dumper_free
-	(struct sieve_code_dumper **dumper);
+	(struct sieve_code_dumper **_dumper);
 pool_t sieve_code_dumper_pool
 	(struct sieve_code_dumper *dumper);
 
-- 
GitLab