changeset 20883:f57ce7cb62eb

lib-dict: Duplicate result value in mempool Duplicate the result value already in callback to avoid it getting lost during async calls. Reported & tested by Pierre Jaury.
author Aki Tuomi <aki.tuomi@dovecot.fi>
date Mon, 17 Oct 2016 19:21:34 +0300
parents 834cc4ef561b
children c9e829c8a36f
files src/lib-dict/dict-client.c
diffstat 1 files changed, 11 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-dict/dict-client.c	Tue Oct 18 10:45:05 2016 +0300
+++ b/src/lib-dict/dict-client.c	Mon Oct 17 19:21:34 2016 +0300
@@ -818,8 +818,9 @@
 }
 
 struct client_dict_sync_lookup {
-	struct dict_lookup_result result;
 	char *error;
+	char *value;
+	int ret;
 };
 
 static void client_dict_lookup_callback(const struct dict_lookup_result *result,
@@ -827,9 +828,11 @@
 {
 	struct client_dict_sync_lookup *lookup = context;
 
-	lookup->result = *result;
+	lookup->ret = result->ret;
 	if (result->ret == -1)
 		lookup->error = i_strdup(result->error);
+	else if (result->ret == 1)
+		lookup->value = i_strdup(result->value);
 }
 
 static int client_dict_lookup(struct dict *_dict, pool_t pool, const char *key,
@@ -838,22 +841,24 @@
 	struct client_dict_sync_lookup lookup;
 
 	memset(&lookup, 0, sizeof(lookup));
-	lookup.result.ret = -2;
+	lookup.ret = -2;
 
 	client_dict_lookup_async(_dict, key, client_dict_lookup_callback, &lookup);
-	if (lookup.result.ret == -2)
+	if (lookup.ret == -2)
 		client_dict_wait(_dict);
 
-	switch (lookup.result.ret) {
+	switch (lookup.ret) {
 	case -1:
 		i_error("dict-client: Lookup '%s' failed: %s", key, lookup.error);
 		i_free(lookup.error);
 		return -1;
 	case 0:
+		i_assert(lookup.value == NULL);
 		*value_r = NULL;
 		return 0;
 	case 1:
-		*value_r = p_strdup(pool, lookup.result.value);
+		*value_r = p_strdup(pool, lookup.value);
+		i_free(lookup.value);
 		return 1;
 	}
 	i_unreached();