From 7cb08ef52fb4e981dfcbcb5ca47827d49efde6a5 Mon Sep 17 00:00:00 2001
From: Vladislav Shpilevoy <v.shpilevoy@tarantool.org>
Date: Thu, 24 Aug 2017 19:37:50 +0300
Subject: [PATCH] sql: fix memleak in space opts

---
 src/box/alter.cc    |  1 +
 src/box/space_def.c | 18 ++++++++++++++++++
 src/box/space_def.h |  3 ++-
 3 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/src/box/alter.cc b/src/box/alter.cc
index 343ff1dd7e..c713226de7 100644
--- a/src/box/alter.cc
+++ b/src/box/alter.cc
@@ -368,6 +368,7 @@ space_def_new_from_tuple(struct tuple *tuple, uint32_t errcode)
 	if (def == NULL)
 		tnt_raise(OutOfMemory, size, "malloc", "def");
 	auto def_guard = make_scoped_guard([=] { space_def_delete(def); });
+	def->opts.sql = NULL;
 	memcpy(def->name, name, name_len);
 	def->name[name_len] = 0;
 	identifier_check_xc(def->name);
diff --git a/src/box/space_def.c b/src/box/space_def.c
index 5c84f20ef4..389ef3fd3d 100644
--- a/src/box/space_def.c
+++ b/src/box/space_def.c
@@ -53,6 +53,15 @@ space_def_dup(const struct space_def *src)
 		return NULL;
 	}
 	memcpy(ret, src, size);
+	if (src->opts.sql != NULL) {
+		ret->opts.sql = strdup(src->opts.sql);
+		if (ret->opts.sql == NULL) {
+			diag_set(OutOfMemory, strlen(src->opts.sql) + 1,
+				 "strdup", "ret->opts.sql");
+			free(ret);
+			return NULL;
+		}
+	}
 	return ret;
 }
 
@@ -78,5 +87,14 @@ space_def_new(uint32_t id, uint32_t uid, uint32_t exact_field_count,
 	memcpy(def->engine_name, engine_name, engine_len);
 	def->engine_name[engine_len] = 0;
 	def->opts = *opts;
+	if (opts->sql != NULL) {
+		def->opts.sql = strdup(opts->sql);
+		if (def->opts.sql == NULL) {
+			diag_set(OutOfMemory, strlen(opts->sql) + 1, "strdup",
+				 "def->opts.sql");
+			free(def);
+			return NULL;
+		}
+	}
 	return def;
 }
diff --git a/src/box/space_def.h b/src/box/space_def.h
index dde3f46352..0b5e4a8e18 100644
--- a/src/box/space_def.h
+++ b/src/box/space_def.h
@@ -51,7 +51,7 @@ struct space_opts {
 	/**
 	 * SQL statement that produced this space.
 	 */
-	const char *sql;
+	char *sql;
 };
 
 extern const struct space_opts space_opts_default;
@@ -93,6 +93,7 @@ space_def_sizeof(uint32_t name_len)
 static inline void
 space_def_delete(struct space_def *def)
 {
+	free(def->opts.sql);
 	free(def);
 }
 
-- 
GitLab