From c70985d47ed3635fe5bedda65e9178f04d84b94e Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Wed, 29 Jan 2020 15:03:21 +0000 Subject: [PATCH] [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++); } -- 2.39.5