commit c70985d: [Rework] Allow to add userdata as symbols options

Vsevolod Stakhov vsevolod at highsecure.ru
Wed Jan 29 15:07:09 UTC 2020


Author: Vsevolod Stakhov
Date: 2020-01-29 15:03:21 +0000
URL: https://github.com/rspamd/rspamd/commit/c70985d47ed3635fe5bedda65e9178f04d84b94e

[Rework] Allow to add userdata as symbols options

---
 src/libserver/composites.c |  8 +++--
 src/libserver/protocol.c   |  3 +-
 src/libserver/task.c       |  3 +-
 src/lua/lua_config.c       | 77 ++++++++++++++++++++++++++++++---------
 src/lua/lua_task.c         | 90 ++++++++++++++++++++++++++++++++++------------
 5 files changed, 138 insertions(+), 43 deletions(-)

diff --git a/src/libserver/composites.c b/src/libserver/composites.c
index 8471d0e93..22fe45818 100644
--- a/src/libserver/composites.c
+++ b/src/libserver/composites.c
@@ -251,7 +251,11 @@ rspamd_composite_process_single_symbol (struct composites_data *cd,
 
 			DL_FOREACH (ms->opts_head, opt) {
 				if (cur_opt->type == RSPAMD_COMPOSITE_OPTION_PLAIN) {
-					if (strcmp (opt->option, cur_opt->data.match) == 0) {
+					gsize mlen = strlen (cur_opt->data.match);
+
+					if (opt->optlen == mlen &&
+						memcmp (opt->option, cur_opt->data.match, mlen) == 0) {
+
 						found = true;
 
 						break;
@@ -259,7 +263,7 @@ rspamd_composite_process_single_symbol (struct composites_data *cd,
 				}
 				else {
 					if (rspamd_regexp_match (cur_opt->data.re,
-							opt->option, 0, FALSE)) {
+							opt->option, opt->optlen, FALSE)) {
 						found = true;
 
 						break;
diff --git a/src/libserver/protocol.c b/src/libserver/protocol.c
index 71f1f363e..20237a7bf 100644
--- a/src/libserver/protocol.c
+++ b/src/libserver/protocol.c
@@ -1130,7 +1130,8 @@ rspamd_metric_symbol_ucl (struct rspamd_task *task, struct rspamd_symbol_result
 		ar = ucl_object_typed_new (UCL_ARRAY);
 
 		DL_FOREACH (sym->opts_head, opt) {
-			ucl_array_append (ar, ucl_object_fromstring (opt->option));
+			ucl_array_append (ar, ucl_object_fromstring_common (opt->option,
+					opt->optlen, 0));
 		}
 
 		ucl_object_insert_key (obj, ar, "options", 0, false);
diff --git a/src/libserver/task.c b/src/libserver/task.c
index c1fcc752f..5c4ca4565 100644
--- a/src/libserver/task.c
+++ b/src/libserver/task.c
@@ -1137,7 +1137,8 @@ rspamd_task_log_metric_res (struct rspamd_task *task,
 						j = 0;
 
 						DL_FOREACH (sym->opts_head, opt) {
-							rspamd_printf_fstring (&symbuf, "%s;", opt->option);
+							rspamd_printf_fstring (&symbuf, "%*s;",
+									(gint)opt->optlen, opt->option);
 
 							if (j >= max_log_elts) {
 								rspamd_printf_fstring (&symbuf, "...;");
diff --git a/src/lua/lua_config.c b/src/lua/lua_config.c
index 266dbd111..24487f1b5 100644
--- a/src/lua/lua_config.c
+++ b/src/lua/lua_config.c
@@ -1267,24 +1267,45 @@ lua_metric_symbol_callback (struct rspamd_task *task,
 
 					for (i = level + first_opt; i <= last_pos; i++) {
 						if (lua_type (L, i) == LUA_TSTRING) {
-							const char *opt = lua_tostring (L, i);
+							gsize optlen;
+							const char *opt = lua_tolstring (L, i, &optlen);
 
-							rspamd_task_add_result_option (task, s, opt);
+							rspamd_task_add_result_option (task, s, opt, optlen);
+						}
+						else if (lua_type (L, i) == LUA_TUSERDATA) {
+							struct rspamd_lua_text *t = lua_check_text (L, i);
+
+							if (t) {
+								rspamd_task_add_result_option (task, s, t->start,
+										t->len);
+							}
 						}
 						else if (lua_type (L, i) == LUA_TTABLE) {
-							lua_pushvalue (L, i);
+							gsize objlen = rspamd_lua_table_size (L, i);
 
-							for (lua_pushnil (L); lua_next (L, -2); lua_pop (L, 1)) {
-								const char *opt = lua_tostring (L, -1);
+							for (guint j = 1; j <= objlen; j ++) {
+								lua_rawgeti (L, i, j);
 
-								rspamd_task_add_result_option (task, s, opt);
-							}
+								if (lua_type (L, -1) == LUA_TSTRING) {
+									gsize optlen;
+									const char *opt = lua_tolstring (L, -1, &optlen);
 
-							lua_pop (L, 1);
+									rspamd_task_add_result_option (task, s, opt, optlen);
+								}
+								else if (lua_type (L, -1) == LUA_TUSERDATA) {
+									struct rspamd_lua_text *t = lua_check_text (L, -1);
+
+									if (t) {
+										rspamd_task_add_result_option (task, s, t->start,
+												t->len);
+									}
+								}
+
+								lua_pop (L, 1);
+							}
 						}
 					}
 				}
-
 			}
 
 			lua_pop (L, nresults);
@@ -1403,20 +1424,42 @@ lua_metric_symbol_callback_return (struct thread_entry *thread_entry, int ret)
 
 				for (i = cd->stack_level + first_opt; i <= last_pos; i++) {
 					if (lua_type (L, i) == LUA_TSTRING) {
-						const char *opt = lua_tostring (L, i);
+						gsize optlen;
+						const char *opt = lua_tolstring (L, i, &optlen);
+
+						rspamd_task_add_result_option (task, s, opt, optlen);
+					}
+					else if (lua_type (L, i) == LUA_TUSERDATA) {
+						struct rspamd_lua_text *t = lua_check_text (L, i);
 
-						rspamd_task_add_result_option (task, s, opt);
+						if (t) {
+							rspamd_task_add_result_option (task, s, t->start,
+									t->len);
+						}
 					}
 					else if (lua_type (L, i) == LUA_TTABLE) {
-						lua_pushvalue (L, i);
+						gsize objlen = rspamd_lua_table_size (L, i);
 
-						for (lua_pushnil (L); lua_next (L, -2); lua_pop (L, 1)) {
-							const char *opt = lua_tostring (L, -1);
+						for (guint j = 1; j <= objlen; j ++) {
+							lua_rawgeti (L, i, j);
 
-							rspamd_task_add_result_option (task, s, opt);
-						}
+							if (lua_type (L, -1) == LUA_TSTRING) {
+								gsize optlen;
+								const char *opt = lua_tolstring (L, -1, &optlen);
+
+								rspamd_task_add_result_option (task, s, opt, optlen);
+							}
+							else if (lua_type (L, -1) == LUA_TUSERDATA) {
+								struct rspamd_lua_text *t = lua_check_text (L, -1);
+
+								if (t) {
+									rspamd_task_add_result_option (task, s, t->start,
+											t->len);
+								}
+							}
 
-						lua_pop (L, 1);
+							lua_pop (L, 1);
+						}
 					}
 				}
 			}
diff --git a/src/lua/lua_task.c b/src/lua/lua_task.c
index 80a00d97b..0b5fab09e 100644
--- a/src/lua/lua_task.c
+++ b/src/lua/lua_task.c
@@ -1837,7 +1837,7 @@ lua_task_insert_result (lua_State * L)
 {
 	LUA_TRACE_POINT;
 	struct rspamd_task *task = lua_check_task (L, 1);
-	const gchar *symbol_name, *param;
+	const gchar *symbol_name;
 	double weight;
 	struct rspamd_symbol_result *s;
 	enum rspamd_symbol_insert_flags flags = RSPAMD_SYMBOL_INSERT_DEFAULT;
@@ -1868,17 +1868,43 @@ lua_task_insert_result (lua_State * L)
 				gint ltype = lua_type (L, i);
 
 				if (ltype == LUA_TSTRING) {
-					param = luaL_checkstring (L, i);
-					rspamd_task_add_result_option (task, s, param);
+					gsize optlen;
+					const char *opt = lua_tolstring (L, i, &optlen);
+
+					rspamd_task_add_result_option (task, s, opt, optlen);
+				}
+				else if (ltype == LUA_TUSERDATA) {
+					struct rspamd_lua_text *t = lua_check_text (L, i);
+
+					if (t) {
+						rspamd_task_add_result_option (task, s, t->start,
+								t->len);
+					}
 				}
 				else if (ltype == LUA_TTABLE) {
-					lua_pushvalue (L, i);
-					lua_pushnil (L);
+					gsize objlen = rspamd_lua_table_size (L, i);
+
+					for (guint j = 1; j <= objlen; j ++) {
+						lua_rawgeti (L, i, j);
+
+						if (lua_type (L, -1) == LUA_TSTRING) {
+							gsize optlen;
+							const char *opt = lua_tolstring (L, -1, &optlen);
 
-					while (lua_next (L, -2)) {
-						if (lua_isstring (L, -1)) {
-							param = lua_tostring (L, -1);
-							rspamd_task_add_result_option (task, s, param);
+							rspamd_task_add_result_option (task, s, opt, optlen);
+						}
+						else if (lua_type (L, -1) == LUA_TUSERDATA) {
+							struct rspamd_lua_text *t = lua_check_text (L, -1);
+
+							if (t) {
+								rspamd_task_add_result_option (task, s, t->start,
+										t->len);
+							}
+							else {
+								return luaL_error (L, "not rspamd_text option in a table "
+													  "when adding symbol  %s: %s type",
+										s->name);
+							}
 						}
 						else {
 							const gchar *tname = lua_typename (L, lua_type (L, -1));
@@ -1891,8 +1917,6 @@ lua_task_insert_result (lua_State * L)
 
 						lua_pop (L, 1);
 					}
-
-					lua_pop (L, 1);
 				}
 				else if (ltype == LUA_TNIL) {
 					/* We have received a NULL option, it is not good but not a fatal error */
@@ -1923,7 +1947,7 @@ lua_task_adjust_result (lua_State * L)
 {
 	LUA_TRACE_POINT;
 	struct rspamd_task *task = lua_check_task (L, 1);
-	const gchar *symbol_name, *param;
+	const gchar *symbol_name;
 	struct rspamd_scan_result *metric_res;
 	struct rspamd_symbol_result *s = NULL;
 	double weight;
@@ -1956,20 +1980,42 @@ lua_task_adjust_result (lua_State * L)
 		if (s) {
 			for (i = 4; i <= top; i++) {
 				if (lua_type (L, i) == LUA_TSTRING) {
-					param = luaL_checkstring (L, i);
-					rspamd_task_add_result_option (task, s, param);
+					gsize optlen;
+					const char *opt = lua_tolstring (L, i, &optlen);
+
+					rspamd_task_add_result_option (task, s, opt, optlen);
+				}
+				else if (lua_type (L, i) == LUA_TUSERDATA) {
+					struct rspamd_lua_text *t = lua_check_text (L, i);
+
+					if (t) {
+						rspamd_task_add_result_option (task, s, t->start,
+								t->len);
+					}
 				}
 				else if (lua_type (L, i) == LUA_TTABLE) {
-					lua_pushvalue (L, i);
-					lua_pushnil (L);
+					gsize objlen = rspamd_lua_table_size (L, i);
+
+					for (guint j = 1; j <= objlen; j ++) {
+						lua_rawgeti (L, i, j);
+
+						if (lua_type (L, -1) == LUA_TSTRING) {
+							gsize optlen;
+							const char *opt = lua_tolstring (L, -1, &optlen);
+
+							rspamd_task_add_result_option (task, s, opt, optlen);
+						}
+						else if (lua_type (L, -1) == LUA_TUSERDATA) {
+							struct rspamd_lua_text *t = lua_check_text (L, -1);
+
+							if (t) {
+								rspamd_task_add_result_option (task, s, t->start,
+										t->len);
+							}
+						}
 
-					while (lua_next (L, -2)) {
-						param = lua_tostring (L, -1);
-						rspamd_task_add_result_option (task, s, param);
 						lua_pop (L, 1);
 					}
-
-					lua_pop (L, 1);
 				}
 			}
 		}
@@ -4374,7 +4420,7 @@ lua_push_symbol_result (lua_State *L,
 			lua_createtable (L, kh_size (s->options), 0);
 
 			DL_FOREACH (s->opts_head, opt) {
-				lua_pushstring (L, (const char*)opt->option);
+				lua_pushlstring (L, opt->option, opt->optlen);
 				lua_rawseti (L, -2, j++);
 			}
 


More information about the Commits mailing list