commit eb5fc65: [Fix] Do not use lightuserdata for traceback

Vsevolod Stakhov vsevolod at highsecure.ru
Fri May 24 15:35:03 UTC 2019


Author: Vsevolod Stakhov
Date: 2019-05-24 14:13:13 +0100
URL: https://github.com/rspamd/rspamd/commit/eb5fc65aca905ad38bab0dae85dba0f9a56d7766

[Fix] Do not use lightuserdata for traceback
LuaJIT limits lightuserdata usage to 47 bits. On Arm64, this leads to
break of the C <-> Lua interoperability using this type.

This rework has changed traceback function behaviour from lightuserdata
opaque pointer (GString * in particular) to luaL_Buffer.

Issue: #2906

---
 src/libmime/message.c                  |  7 +--
 src/libmime/mime_expressions.c         |  9 +---
 src/libserver/cfg_rcl.c                | 35 ++++-----------
 src/libserver/cfg_utils.c              |  8 +---
 src/libserver/re_cache.c               |  9 +---
 src/libstat/backends/redis_backend.c   |  8 ++--
 src/libstat/backends/sqlite3_backend.c | 16 +++----
 src/libstat/stat_config.c              |  9 +---
 src/libstat/stat_process.c             | 13 +-----
 src/lua/lua_common.c                   | 81 ++++++++++++++++------------------
 src/lua/lua_common.h                   |  3 +-
 src/lua/lua_config.c                   | 51 +++++----------------
 src/lua/lua_dns_resolver.c             |  9 +---
 src/lua/lua_expression.c               |  4 +-
 src/lua/lua_task.c                     |  4 +-
 src/lua/lua_thread_pool.c              | 18 ++++----
 src/lua/lua_upstream.c                 |  4 +-
 src/lua/lua_worker.c                   | 24 +++++-----
 src/plugins/dkim_check.c               |  7 ++-
 src/plugins/fuzzy_check.c              | 28 +++---------
 src/plugins/surbl.c                    |  4 +-
 src/rspamd_proxy.c                     | 20 ++-------
 22 files changed, 117 insertions(+), 254 deletions(-)

diff --git a/src/libmime/message.c b/src/libmime/message.c
index 6211ea2f3..cd3772c78 100644
--- a/src/libmime/message.c
+++ b/src/libmime/message.c
@@ -716,11 +716,8 @@ rspamd_message_process_plain_text_part (struct rspamd_task *task,
 					text_part->utf_raw_content->len);
 
 			if (lua_pcall (L, 1, 1, err_idx) != 0) {
-				GString *tb;
-
-				tb = lua_touserdata (L, -1);
-				msg_err_task ("cannot call lua lua_ical.ical_txt_values: %s", tb->str);
-				g_string_free (tb, TRUE);
+				msg_err_task ("cannot call lua lua_ical.ical_txt_values: %s",
+						lua_tostring (L, -1));
 				lua_settop (L, err_idx - 1);
 
 				return FALSE;
diff --git a/src/libmime/mime_expressions.c b/src/libmime/mime_expressions.c
index 4a0071f28..7a0c27f1b 100644
--- a/src/libmime/mime_expressions.c
+++ b/src/libmime/mime_expressions.c
@@ -1114,7 +1114,6 @@ rspamd_mime_expr_process (void *ud, rspamd_expression_atom_t *atom)
 	}
 	else if (mime_atom->type == MIME_ATOM_LOCAL_LUA_FUNCTION) {
 		gint err_idx;
-		GString *tb;
 
 		L = task->cfg->lua_state;
 		lua_pushcfunction (L, &rspamd_lua_traceback);
@@ -1124,13 +1123,9 @@ rspamd_mime_expr_process (void *ud, rspamd_expression_atom_t *atom)
 		rspamd_lua_task_push (L, task);
 
 		if (lua_pcall (L, 1, 1, err_idx) != 0) {
-			tb = lua_touserdata (L, -1);
-			msg_info_task ("lua call to local function for atom '%s' failed: %v",
+			msg_info_task ("lua call to local function for atom '%s' failed: %s",
 					mime_atom->str,
-					tb);
-			if (tb) {
-				g_string_free (tb, TRUE);
-			}
+					lua_tostring (L, -1));
 		}
 		else {
 			if (lua_type (L, -1) == LUA_TBOOLEAN) {
diff --git a/src/libserver/cfg_rcl.c b/src/libserver/cfg_rcl.c
index 9df9e4aa1..d5e30d8a7 100644
--- a/src/libserver/cfg_rcl.c
+++ b/src/libserver/cfg_rcl.c
@@ -753,7 +753,6 @@ rspamd_rcl_lua_handler (rspamd_mempool_t *pool, const ucl_object_t *obj,
 			ucl_object_tostring (obj));
 	gchar *cur_dir, *lua_dir, *lua_file, *tmp1, *tmp2;
 	lua_State *L = cfg->lua_state;
-	GString *tb;
 	gint err_idx;
 
 	tmp1 = g_strdup (lua_src);
@@ -788,15 +787,13 @@ rspamd_rcl_lua_handler (rspamd_mempool_t *pool, const ucl_object_t *obj,
 
 			/* Now do it */
 			if (lua_pcall (L, 0, 0, err_idx) != 0) {
-				tb = lua_touserdata (L, -1);
 				g_set_error (err,
 						CFG_RCL_ERROR,
 						EINVAL,
 						"cannot init lua file %s: %s",
 						lua_src,
-						tb->str);
-				g_string_free (tb, TRUE);
-				lua_pop (L, 2);
+						lua_tostring (L, -1));
+				lua_settop (L, 0);
 
 				if (chdir (cur_dir) == -1) {
 					msg_err_config ("cannot chdir to %s: %s", cur_dir,
@@ -1241,7 +1238,6 @@ rspamd_rcl_classifier_handler (rspamd_mempool_t *pool,
 				const gchar *lua_script;
 				gsize slen;
 				gint err_idx, ref_idx;
-				GString *tb = NULL;
 
 				lua_script = ucl_object_tolstring (cur, &slen);
 				L = cfg->lua_state;
@@ -1263,13 +1259,11 @@ rspamd_rcl_classifier_handler (rspamd_mempool_t *pool,
 
 				/* Now do it */
 				if (lua_pcall (L, 0, 1, err_idx) != 0) {
-					tb = lua_touserdata (L, -1);
 					g_set_error (err,
 							CFG_RCL_ERROR,
 							EINVAL,
 							"cannot init lua condition script: %s",
-							tb->str);
-					g_string_free (tb, TRUE);
+							lua_tostring (L, -1));
 					lua_settop (L, 0);
 
 					return FALSE;
@@ -3484,7 +3478,6 @@ rspamd_rcl_maybe_apply_lua_transform (struct rspamd_config *cfg)
 {
 	lua_State *L = cfg->lua_state;
 	gint err_idx, ret;
-	GString *tb;
 	gchar str[PATH_MAX];
 	static const char *transform_script = "lua_cfg_transform";
 
@@ -3518,13 +3511,8 @@ rspamd_rcl_maybe_apply_lua_transform (struct rspamd_config *cfg)
 	ucl_object_push_lua (L, cfg->rcl_obj, true);
 
 	if ((ret = lua_pcall (L, 1, 2, err_idx)) != 0) {
-		tb = lua_touserdata (L, -1);
-		msg_err ("call to rspamadm lua script failed (%d): %v", ret, tb);
-
-		if (tb) {
-			g_string_free (tb, TRUE);
-		}
-
+		msg_err ("call to rspamadm lua script failed (%d): %v", ret,
+				lua_tostring (L, -1));
 		lua_settop (L, 0);
 
 		return;
@@ -3588,11 +3576,8 @@ rspamd_rcl_jinja_handler (struct ucl_parser *parser,
 	lua_pushboolean (L, false);
 
 	if (lua_pcall (L, 3, 1, err_idx) != 0) {
-		GString *tb;
-
-		tb = lua_touserdata (L, -1);
-		msg_err_config ("cannot call lua jinja_template script: %s", tb->str);
-		g_string_free (tb, TRUE);
+		msg_err_config ("cannot call lua jinja_template script: %s",
+				lua_tostring (L, -1));
 		lua_settop (L, err_idx - 1);
 
 		return false;
@@ -3856,12 +3841,8 @@ rspamd_config_read (struct rspamd_config *cfg,
 				rspamd_lua_setclass (L, "rspamd{config}", -1);
 
 				if (lua_pcall (L, 1, 0, err_idx) != 0) {
-					GString *tb;
-
-					tb = lua_touserdata (L, -1);
 					msg_err_config ("cannot call lua init_debug_logging script: %s",
-							tb->str);
-					g_string_free (tb, TRUE);
+							lua_tostring (L, -1));
 					lua_settop (L, err_idx - 1);
 
 					return FALSE;
diff --git a/src/libserver/cfg_utils.c b/src/libserver/cfg_utils.c
index 4d717c860..586625184 100644
--- a/src/libserver/cfg_utils.c
+++ b/src/libserver/cfg_utils.c
@@ -829,12 +829,8 @@ rspamd_config_post_load (struct rspamd_config *cfg,
 		if (rspamd_lua_require_function (cfg->lua_state, "lua_squeeze_rules",
 				"squeeze_init")) {
 			if (lua_pcall (L, 0, 0, err_idx) != 0) {
-				GString *tb = lua_touserdata (L, -1);
-				msg_err_config ("call to squeeze_init script failed: %v", tb);
-
-				if (tb) {
-					g_string_free (tb, TRUE);
-				}
+				msg_err_config ("call to squeeze_init script failed: %s",
+						lua_tostring (L, -1));
 			}
 		}
 
diff --git a/src/libserver/re_cache.c b/src/libserver/re_cache.c
index f4f190ed5..4f14f6ff8 100644
--- a/src/libserver/re_cache.c
+++ b/src/libserver/re_cache.c
@@ -801,7 +801,6 @@ rspamd_re_cache_process_selector (struct rspamd_task *task,
 	khiter_t k;
 	lua_State *L;
 	gint err_idx, ret;
-	GString *tb;
 	struct rspamd_task **ptask;
 	gboolean result = FALSE;
 	struct rspamd_re_cache *cache = rt->cache;
@@ -845,13 +844,9 @@ rspamd_re_cache_process_selector (struct rspamd_task *task,
 	rspamd_lua_setclass (L, "rspamd{task}", -1);
 
 	if ((ret = lua_pcall (L, 1, 1, err_idx)) != 0) {
-		tb = lua_touserdata (L, -1);
 		msg_err_task ("call to selector %s "
-						"failed (%d): %v", name, ret, tb);
-
-		if (tb) {
-			g_string_free (tb, TRUE);
-		}
+						"failed (%d): %s", name, ret,
+						lua_tostring (L, -1));
 	}
 	else {
 		gsize slen;
diff --git a/src/libstat/backends/redis_backend.c b/src/libstat/backends/redis_backend.c
index d54767c12..5976968a7 100644
--- a/src/libstat/backends/redis_backend.c
+++ b/src/libstat/backends/redis_backend.c
@@ -148,7 +148,6 @@ rspamd_redis_expand_object (const gchar *pattern,
 	struct rspamd_statfile_config *stcf;
 	lua_State *L = NULL;
 	struct rspamd_task **ptask;
-	GString *tb;
 	const gchar *rcpt = NULL;
 	gint err_idx;
 
@@ -172,16 +171,15 @@ rspamd_redis_expand_object (const gchar *pattern,
 			rspamd_lua_setclass (L, "rspamd{task}", -1);
 
 			if (lua_pcall (L, 1, 1, err_idx) != 0) {
-				tb = lua_touserdata (L, -1);
-				msg_err_task ("call to user extraction script failed: %v", tb);
-				g_string_free (tb, TRUE);
+				msg_err_task ("call to user extraction script failed: %s",
+						lua_tostring (L, -1));
 			}
 			else {
 				rcpt = rspamd_mempool_strdup (task->task_pool, lua_tostring (L, -1));
 			}
 
 			/* Result + error function */
-			lua_pop (L, 2);
+			lua_settop (L, err_idx - 1);
 		}
 
 		if (rcpt) {
diff --git a/src/libstat/backends/sqlite3_backend.c b/src/libstat/backends/sqlite3_backend.c
index cf7291ee0..61bc5bbd3 100644
--- a/src/libstat/backends/sqlite3_backend.c
+++ b/src/libstat/backends/sqlite3_backend.c
@@ -314,7 +314,6 @@ rspamd_sqlite3_get_user (struct rspamd_stat_sqlite3_db *db,
 	const gchar *user = NULL;
 	struct rspamd_task **ptask;
 	lua_State *L = db->L;
-	GString *tb;
 
 	if (db->cbref_user == -1) {
 		user = rspamd_task_get_principal_recipient (task);
@@ -330,16 +329,15 @@ rspamd_sqlite3_get_user (struct rspamd_stat_sqlite3_db *db,
 		rspamd_lua_setclass (L, "rspamd{task}", -1);
 
 		if (lua_pcall (L, 1, 1, err_idx) != 0) {
-			tb = lua_touserdata (L, -1);
-			msg_err_task ("call to user extraction script failed: %v", tb);
-			g_string_free (tb, TRUE);
+			msg_err_task ("call to user extraction script failed: %s",
+					lua_tostring (L, -1));
 		}
 		else {
 			user = rspamd_mempool_strdup (task->task_pool, lua_tostring (L, -1));
 		}
 
 		/* Result + error function */
-		lua_pop (L, 2);
+		lua_settop (L, err_idx - 1);
 	}
 
 
@@ -377,7 +375,6 @@ rspamd_sqlite3_get_language (struct rspamd_stat_sqlite3_db *db,
 	struct rspamd_mime_text_part *tp;
 	struct rspamd_task **ptask;
 	lua_State *L = db->L;
-	GString *tb;
 
 	if (db->cbref_language == -1) {
 		for (i = 0; i < task->text_parts->len; i++) {
@@ -401,9 +398,8 @@ rspamd_sqlite3_get_language (struct rspamd_stat_sqlite3_db *db,
 		rspamd_lua_setclass (L, "rspamd{task}", -1);
 
 		if (lua_pcall (L, 1, 1, err_idx) != 0) {
-			tb = lua_touserdata (L, -1);
-			msg_err_task ("call to language extraction script failed: %v", tb);
-			g_string_free (tb, TRUE);
+			msg_err_task ("call to language extraction script failed: %s",
+					lua_tostring (L, -1));
 		}
 		else {
 			language = rspamd_mempool_strdup (task->task_pool,
@@ -411,7 +407,7 @@ rspamd_sqlite3_get_language (struct rspamd_stat_sqlite3_db *db,
 		}
 
 		/* Result + error function */
-		lua_pop (L, 2);
+		lua_settop (L, err_idx - 1);
 	}
 
 
diff --git a/src/libstat/stat_config.c b/src/libstat/stat_config.c
index 101db4fe6..272a64ddf 100644
--- a/src/libstat/stat_config.c
+++ b/src/libstat/stat_config.c
@@ -189,7 +189,6 @@ rspamd_stat_init (struct rspamd_config *cfg, struct event_base *ev_base)
 			else {
 				/* Call this function to obtain closure */
 				gint err_idx, ret;
-				GString *tb;
 				struct rspamd_config **pcfg;
 
 				lua_pushcfunction (L, &rspamd_lua_traceback);
@@ -201,13 +200,9 @@ rspamd_stat_init (struct rspamd_config *cfg, struct event_base *ev_base)
 				rspamd_lua_setclass (L, "rspamd{config}", -1);
 
 				if ((ret = lua_pcall (L, 1, 1, err_idx)) != 0) {
-					tb = lua_touserdata (L, -1);
 					msg_err_config ("call to gen_stat_tokens lua "
-									"script failed (%d): %v", ret, tb);
-
-					if (tb) {
-						g_string_free (tb, TRUE);
-					}
+									"script failed (%d): %s", ret,
+									lua_tostring (L, -1));
 				}
 				else {
 					if (lua_type (L, -1) != LUA_TFUNCTION) {
diff --git a/src/libstat/stat_process.c b/src/libstat/stat_process.c
index d097e12e0..901d62a2b 100644
--- a/src/libstat/stat_process.c
+++ b/src/libstat/stat_process.c
@@ -46,7 +46,6 @@ rspamd_stat_tokenize_parts_metadata (struct rspamd_stat_ctx *st_ctx,
 
 	if (st_ctx->lua_stat_tokens_ref != -1) {
 		gint err_idx, ret;
-		GString *tb;
 		struct rspamd_task **ptask;
 
 		lua_pushcfunction (L, &rspamd_lua_traceback);
@@ -58,13 +57,8 @@ rspamd_stat_tokenize_parts_metadata (struct rspamd_stat_ctx *st_ctx,
 		rspamd_lua_setclass (L, "rspamd{task}", -1);
 
 		if ((ret = lua_pcall (L, 1, 1, err_idx)) != 0) {
-			tb = lua_touserdata (L, -1);
 			msg_err_task ("call to stat_tokens lua "
-							"script failed (%d): %v", ret, tb);
-
-			if (tb) {
-				g_string_free (tb, TRUE);
-			}
+							"script failed (%d): %s", ret, lua_tostring (L, -1));
 		}
 		else {
 			if (lua_type (L, -1) != LUA_TTABLE) {
@@ -913,7 +907,6 @@ rspamd_stat_check_autolearn (struct rspamd_task *task)
 	struct rspamd_metric_result *mres = NULL;
 	struct rspamd_task **ptask;
 	lua_State *L;
-	GString *tb;
 	guint i;
 	gint err_idx;
 	gboolean ret = FALSE;
@@ -1011,10 +1004,8 @@ rspamd_stat_check_autolearn (struct rspamd_task *task)
 						rspamd_lua_setclass (L, "rspamd{task}", -1);
 
 						if (lua_pcall (L, 1, 1, err_idx) != 0) {
-							tb = lua_touserdata (L, -1);
 							msg_err_task ("call to autolearn script failed: "
-									"%v", tb);
-							g_string_free (tb, TRUE);
+									"%s", lua_tostring (L, -1));
 						}
 						else {
 							lua_ret = lua_tostring (L, -1);
diff --git a/src/lua/lua_common.c b/src/lua/lua_common.c
index 542726da4..c2940c9ab 100644
--- a/src/lua/lua_common.c
+++ b/src/lua/lua_common.c
@@ -510,13 +510,10 @@ rspamd_lua_load_env (lua_State *L, const char *fname, gint tbl_pos, GError **err
 	}
 
 	if (ret && lua_pcall (L, 0, 1, err_idx) != 0) {
-		GString *tb = lua_touserdata (L, -1);
 		g_set_error (err, g_quark_from_static_string ("lua_env"), errno,
 				"cannot init lua file %s: %s",
 				fname,
-				tb->str);
-		g_string_free (tb, TRUE);
-
+				lua_tostring (L, -1));
 		ret = FALSE;
 	}
 
@@ -1048,7 +1045,6 @@ rspamd_init_lua_filters (struct rspamd_config *cfg, gboolean force_load)
 	GList *cur;
 	struct script_module *module;
 	lua_State *L = cfg->lua_state;
-	GString *tb;
 	gint err_idx;
 
 	cur = g_list_first (cfg->script_modules);
@@ -1086,14 +1082,11 @@ rspamd_init_lua_filters (struct rspamd_config *cfg, gboolean force_load)
 			lua_setglobal (L, "rspamd_config");
 
 			if (lua_pcall (L, 0, 0, err_idx) != 0) {
-				tb = lua_touserdata (L, -1);
-				msg_err_config ("init of %s failed: %v",
+				msg_err_config ("init of %s failed: %s",
 						module->path,
-						tb);
-
-				g_string_free (tb, TRUE);
-				lua_pop (L, 2); /* Result and error function */
+						lua_tostring (L, -1));
 
+				lua_settop (L, err_idx - 1);
 				rspamd_plugins_table_push_elt (L, "disabled_failed",
 						module->name);
 
@@ -1667,44 +1660,41 @@ rspamd_lua_parse_table_arguments (lua_State *L, gint pos,
 }
 
 static void
-rspamd_lua_traceback_string (lua_State *L, GString *s)
+rspamd_lua_traceback_string (lua_State *L, luaL_Buffer *buf)
 {
-	gint i = 1;
+	gint i = 1, r;
 	lua_Debug d;
+	gchar tmp[256];
 
 	while (lua_getstack (L, i++, &d)) {
 		lua_getinfo (L, "nSl", &d);
-		g_string_append_printf (s, " [%d]:{%s:%d - %s [%s]};",
+		r = rspamd_snprintf (tmp, sizeof (tmp), " [%d]:{%s:%d - %s [%s]};",
 				i - 1, d.short_src, d.currentline,
 				(d.name ? d.name : "<unknown>"), d.what);
+		luaL_addlstring (buf, tmp, r);
 	}
 }
 
 gint
 rspamd_lua_traceback (lua_State *L)
 {
+	luaL_Buffer b;
 
-	GString *tb;
-
-	tb = rspamd_lua_get_traceback_string (L);
-
-	lua_pushlightuserdata (L, tb);
+	luaL_buffinit (L, &b);
+	rspamd_lua_get_traceback_string (L, &b);
+	luaL_pushresult (&b);
 
 	return 1;
 }
 
-GString *
-rspamd_lua_get_traceback_string (lua_State *L)
+void
+rspamd_lua_get_traceback_string (lua_State *L, luaL_Buffer *buf)
 {
-	GString *tb;
 	const gchar *msg = lua_tostring (L, -1);
 
-	tb = g_string_sized_new (100);
-	g_string_append_printf (tb, "%s; trace:", msg);
-
-	rspamd_lua_traceback_string (L, tb);
-
-	return tb;
+	luaL_addstring (buf, msg);
+	luaL_addstring (buf, "; trace:");
+	rspamd_lua_traceback_string (L, buf);
 }
 
 guint
@@ -1730,7 +1720,6 @@ rspamd_lua_check_udata_common (lua_State *L, gint pos, const gchar *classname,
 		gboolean fatal)
 {
 	void *p = lua_touserdata (L, pos);
-	GString *err_msg;
 	guint i, top = lua_gettop (L);
 
 	if (p == NULL) {
@@ -1769,12 +1758,19 @@ err:
 			actual_classname = lua_typename (L, lua_type (L, pos));
 		}
 
-		err_msg = g_string_sized_new (100);
-		rspamd_printf_gstring (err_msg, "expected %s at position %d, but userdata has "
-										"%s metatable; trace: ",
+		luaL_Buffer buf;
+		gchar tmp[512];
+		gint r;
+
+		luaL_buffinit (L, &buf);
+		r = rspamd_snprintf (tmp, sizeof (tmp),
+				"expected %s at position %d, but userdata has "
+				"%s metatable; trace: ",
 				classname, pos, actual_classname);
-		rspamd_lua_traceback_string (L, err_msg);
-		rspamd_printf_gstring (err_msg, " stack(%d): ", top);
+		luaL_addlstring (&buf, tmp, r);
+		rspamd_lua_traceback_string (L, &buf);
+		r = rspamd_snprintf (tmp, sizeof (tmp), " stack(%d): ", top);
+		luaL_addlstring (&buf, tmp, r);
 
 		for (i = 1; i <= MIN (top, 10); i ++) {
 			if (lua_type (L, i) == LUA_TUSERDATA) {
@@ -1791,17 +1787,19 @@ err:
 					clsname = lua_typename (L, lua_type (L, i));
 				}
 
-				rspamd_printf_gstring (err_msg, "[%d: ud=%s] ", i,
+				r = rspamd_snprintf (tmp, sizeof (tmp), "[%d: ud=%s] ", i,
 						clsname);
+				luaL_addlstring (&buf, tmp, r);
 			}
 			else {
-				rspamd_printf_gstring (err_msg, "[%d: %s] ", i,
+				r = rspamd_snprintf (tmp, sizeof (tmp), "[%d: %s] ", i,
 						lua_typename (L, lua_type (L, i)));
+				luaL_addlstring (&buf, tmp, r);
 			}
 		}
 
-		msg_err ("lua type error: %v", err_msg);
-		g_string_free (err_msg, TRUE);
+		luaL_pushresult (&buf);
+		msg_err ("lua type error: %s", lua_tostring (L, -1));
 	}
 
 	lua_settop (L, top);
@@ -1982,11 +1980,8 @@ rspamd_lua_try_load_redis (lua_State *L, const ucl_object_t *obj,
 	lua_pushboolean (L, false); /* no_fallback */
 
 	if (lua_pcall (L, 3, 1, err_idx) != 0) {
-		GString *tb;
-
-		tb = lua_touserdata (L, -1);
-		msg_err_config ("cannot call lua try_load_redis_servers script: %s", tb->str);
-		g_string_free (tb, TRUE);
+		msg_err_config ("cannot call lua try_load_redis_servers script: %s",
+				lua_tostring (L, -1));
 		lua_settop (L, 0);
 
 		return FALSE;
diff --git a/src/lua/lua_common.h b/src/lua/lua_common.h
index 214fffca6..776baf3b9 100644
--- a/src/lua/lua_common.h
+++ b/src/lua/lua_common.h
@@ -348,8 +348,7 @@ gint rspamd_lua_traceback (lua_State *L);
  * @param L
  * @return
  */
-GString *
-rspamd_lua_get_traceback_string (lua_State *L);
+void rspamd_lua_get_traceback_string (lua_State *L, luaL_Buffer *buf);
 
 /**
  * Returns size of table at position `tbl_pos`
diff --git a/src/lua/lua_config.c b/src/lua/lua_config.c
index a60ad8493..cc0fa44ee 100644
--- a/src/lua/lua_config.c
+++ b/src/lua/lua_config.c
@@ -1130,7 +1130,6 @@ lua_metric_symbol_callback (struct rspamd_task *task,
 	struct rspamd_task **ptask;
 	gint level = lua_gettop (cd->L), nresults, err_idx, ret;
 	lua_State *L = cd->L;
-	GString *tb;
 	struct rspamd_symbol_result *s;
 
 	cd->item = item;
@@ -1152,13 +1151,9 @@ lua_metric_symbol_callback (struct rspamd_task *task,
 	*ptask = task;
 
 	if ((ret = lua_pcall (L, 1, LUA_MULTRET, err_idx)) != 0) {
-		tb = lua_touserdata (L, -1);
-		msg_err_task ("call to (%s) failed (%d): %v", cd->symbol, ret, tb);
-
-		if (tb) {
-			g_string_free (tb, TRUE);
-			lua_pop (L, 1);
-		}
+		msg_err_task ("call to (%s) failed (%d): %s", cd->symbol, ret,
+				lua_tostring (L, -1));
+		lua_settop (L, err_idx); /* Not -1 here, as err_func is popped below */
 	}
 	else {
 		nresults = lua_gettop (L) - level;
@@ -1395,12 +1390,8 @@ rspamd_lua_squeeze_rule (lua_State *L,
 
 			/* Now call for squeeze function */
 			if (lua_pcall (L, 2, 1, err_idx) != 0) {
-				GString *tb = lua_touserdata (L, -1);
-				msg_err_config ("call to squeeze_virtual failed: %v", tb);
-
-				if (tb) {
-					g_string_free (tb, TRUE);
-				}
+				msg_err_config ("call to squeeze_virtual failed: %s",
+						lua_tostring (L, -1));
 			}
 
 			ret = lua_tonumber (L, -1);
@@ -1449,12 +1440,8 @@ rspamd_lua_squeeze_rule (lua_State *L,
 
 			/* Now call for squeeze function */
 			if (lua_pcall (L, 3, 1, err_idx) != 0) {
-				GString *tb = lua_touserdata (L, -1);
-				msg_err_config ("call to squeeze_rule failed: %v", tb);
-
-				if (tb) {
-					g_string_free (tb, TRUE);
-				}
+				msg_err_config ("call to squeeze_rule failed: %s",
+						lua_tostring (L, -1));
 			}
 
 			ret = lua_tonumber (L, -1);
@@ -2215,12 +2202,8 @@ rspamd_lua_squeeze_dependency (lua_State *L, struct rspamd_config *cfg,
 		lua_pushstring (L, parent);
 
 		if (lua_pcall (L, 2, 1, err_idx) != 0) {
-			GString *tb = lua_touserdata (L, -1);
-			msg_err_config ("call to squeeze_dependency script failed: %v", tb);
-
-			if (tb) {
-				g_string_free (tb, TRUE);
-			}
+			msg_err_config ("call to squeeze_dependency script failed: %s",
+					lua_tostring (L, -1));
 		}
 		else {
 			ret = lua_toboolean (L, -1);
@@ -3732,7 +3715,6 @@ lua_include_trace_cb (struct ucl_parser *parser,
 	struct rspamd_lua_include_trace_cbdata *cbdata =
 			(struct rspamd_lua_include_trace_cbdata *)user_data;
 	gint err_idx;
-	GString *tb;
 	lua_State *L;
 
 	L = cbdata->L;
@@ -3760,11 +3742,7 @@ lua_include_trace_cb (struct ucl_parser *parser,
 	}
 
 	if (lua_pcall (L, 4, 0, err_idx) != 0) {
-		tb = lua_touserdata (L, -1);
-		msg_err ("lua call to local include trace failed: %v", tb);
-		if (tb) {
-			g_string_free (tb, TRUE);
-		}
+		msg_err ("lua call to local include trace failed: %s", lua_tostring (L, -1));
 	}
 
 	lua_settop (L, err_idx - 1);
@@ -4014,7 +3992,6 @@ lua_config_register_re_selector (lua_State *L)
 				}
 				else {
 					gint err_idx, ret;
-					GString *tb;
 					struct rspamd_config **pcfg;
 
 					lua_pushcfunction (L, &rspamd_lua_traceback);
@@ -4030,13 +4007,9 @@ lua_config_register_re_selector (lua_State *L)
 					lua_pushstring (L, delimiter);
 
 					if ((ret = lua_pcall (L, 3, 1, err_idx)) != 0) {
*** OUTPUT TRUNCATED, 435 LINES SKIPPED ***


More information about the Commits mailing list