From bbfaef3b02d383db2b3be81750f60a9a12552b33 Mon Sep 17 00:00:00 2001
From: Ilya Verbin <iverbin@tarantool.org>
Date: Wed, 23 Aug 2023 20:39:21 +0300
Subject: [PATCH] lua: fix uninitialized var usage in
 luamp_encode_with_translation

`*type_out` was set to uninitialized value for `field->type == MP_EXT`.
This was introduced by commit 9f9142d64289 ("box: cleanup on tuple encoding
failure")

Closes #9023

NO_DOC=bugfix
NO_CHANGELOG=not user-visible
---
 src/lua/msgpack.c       |  1 +
 test/unit/lua_msgpack.c | 53 ++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 53 insertions(+), 1 deletion(-)

diff --git a/src/lua/msgpack.c b/src/lua/msgpack.c
index dd25017b32..5868c6a3a9 100644
--- a/src/lua/msgpack.c
+++ b/src/lua/msgpack.c
@@ -324,6 +324,7 @@ luamp_encode_with_translation_r(struct lua_State *L,
 		type = MP_ARRAY;
 		break;
 	case MP_EXT:
+		type = MP_EXT;
 		switch (field->ext_type) {
 		case MP_DECIMAL:
 			mpstream_encode_decimal(stream, field->decval);
diff --git a/test/unit/lua_msgpack.c b/test/unit/lua_msgpack.c
index 20d45d2558..ab8a996e60 100644
--- a/test/unit/lua_msgpack.c
+++ b/test/unit/lua_msgpack.c
@@ -11,6 +11,7 @@
 #include "mpstream/mpstream.h"
 
 #include "small/ibuf.h"
+#include "tt_uuid.h"
 
 #define UNIT_TAP_COMPATIBLE 1
 #include "unit.h"
@@ -22,6 +23,53 @@ mpstream_error_mock(void *ctx)
 	(void)ctx;
 }
 
+/**
+ * Checks encoding to `MP_EXT`.
+ */
+static void
+test_encode_ext(lua_State *L)
+{
+	plan(2);
+	header();
+
+	struct mh_strnu32_t *translation = mh_strnu32_new();
+	const char *alias = "x";
+	struct mh_strnu32_node_t node = {
+		.str = alias,
+		.len = strlen(alias),
+		.hash = lua_hash(alias, strlen(alias)),
+		.val = 0
+	};
+	mh_strnu32_put(translation, &node, NULL, NULL);
+
+	struct ibuf *ibuf = cord_ibuf_take();
+	struct mpstream stream;
+	mpstream_init(&stream, ibuf, ibuf_reserve_cb, ibuf_alloc_cb,
+		      mpstream_error_mock, L);
+
+	enum mp_type type;
+	struct tt_uuid uuid;
+	memset(&uuid, 0, sizeof(uuid));
+	luaT_pushuuid(L, &uuid);
+	luamp_encode_with_translation(L, luaL_msgpack_default, &stream, 1,
+				      translation, &type);
+	lua_pop(L, 1);
+	mpstream_flush(&stream);
+	const char *mp_expected = "\xd8\x02\x00\x00\x00\x00\x00\x00\x00"
+				  "\x00\x00\x00\x00\x00\x00\x00\x00\x00";
+	ok(strncmp(ibuf->buf, mp_expected, ibuf_used(ibuf)) == 0,
+	   "UUID is correctly encoded as MP_EXT");
+	ok(type == MP_EXT, "type of UUID is MP_EXT");
+	ibuf_reset(ibuf);
+	mpstream_reset(&stream);
+
+	cord_ibuf_drop(ibuf);
+	mh_strnu32_delete(translation);
+
+	footer();
+	check_plan();
+}
+
 /**
  * Checks that translation of first-level `MP_MAP` keys is done correctly.
  */
@@ -149,7 +197,7 @@ test_translation_in_indexation(struct lua_State *L)
 int
 main(void)
 {
-	plan(2);
+	plan(3);
 	header();
 
 	struct lua_State *L = luaT_newteststate();
@@ -157,10 +205,13 @@ main(void)
 	memory_init();
 	fiber_init(fiber_c_invoke);
 
+	tarantool_lua_error_init(L);
+	tarantool_lua_utils_init(L);
 	tarantool_lua_serializer_init(L);
 	luaopen_msgpack(L);
 	lua_pop(L, 1);
 
+	test_encode_ext(L);
 	test_translation_in_encoding(L);
 	test_translation_in_indexation(L);
 
-- 
GitLab