From bcd36f79596a8666217d29088f6b0040c6cf092b Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Tue, 5 Mar 2024 15:29:33 +0000 Subject: [PATCH] [Rework] Rework dynamic usage --- src/lua/lua_classnames.c | 100 +++++++++++++++++++++++++++++++++++++++ src/lua/lua_classnames.h | 8 ++++ src/lua/lua_common.c | 10 ++-- 3 files changed, 112 insertions(+), 6 deletions(-) diff --git a/src/lua/lua_classnames.c b/src/lua/lua_classnames.c index 5d67e2c19..7041a8ca1 100644 --- a/src/lua/lua_classnames.c +++ b/src/lua/lua_classnames.c @@ -14,6 +14,9 @@ * limitations under the License. */ +#include "config.h" +#include "libutil/str_util.h" +#include "khash.h" #include "lua_classnames.h" const char *rspamd_archive_classname = "rspamd{archive}"; @@ -64,3 +67,100 @@ const char *rspamd_url_classname = "rspamd{url}"; const char *rspamd_worker_classname = "rspamd{worker}"; const char *rspamd_zstd_compress_classname = "rspamd{zstd_compress}"; const char *rspamd_zstd_decompress_classname = "rspamd{zstd_decompress}"; + +KHASH_INIT(rspamd_lua_static_classes, const char *, const char *, 1, rspamd_str_hash, rspamd_str_equal); + +static khash_t(rspamd_lua_static_classes) *lua_static_classes = NULL; + +#define CLASS_PUT_STR(s) \ + do { \ + int _r = 0; \ + khiter_t it = kh_put(rspamd_lua_static_classes, lua_static_classes, #s, &_r); \ + g_assert(_r > 0); \ + kh_value(lua_static_classes, it) = rspamd_##s##_classname; \ + } while (0) + +RSPAMD_CONSTRUCTOR(rspamd_lua_init_classnames) +{ + lua_static_classes = kh_init(rspamd_lua_static_classes); + kh_resize(rspamd_lua_static_classes, lua_static_classes, RSPAMD_MAX_LUA_CLASSES); + + CLASS_PUT_STR(archive); + CLASS_PUT_STR(cdb_builder); + CLASS_PUT_STR(cdb); + CLASS_PUT_STR(classifier); + CLASS_PUT_STR(config); + CLASS_PUT_STR(cryptobox_hash); + CLASS_PUT_STR(cryptobox_keypair); + CLASS_PUT_STR(cryptobox_pubkey); + CLASS_PUT_STR(cryptobox_secretbox); + CLASS_PUT_STR(cryptobox_signature); + CLASS_PUT_STR(csession); + CLASS_PUT_STR(ev_base); + CLASS_PUT_STR(expr); + CLASS_PUT_STR(html_tag); + CLASS_PUT_STR(html); + CLASS_PUT_STR(image); + CLASS_PUT_STR(int64); + CLASS_PUT_STR(ip); + CLASS_PUT_STR(kann_node); + CLASS_PUT_STR(kann); + CLASS_PUT_STR(map); + CLASS_PUT_STR(mempool); + CLASS_PUT_STR(mimepart); + CLASS_PUT_STR(monitored); + CLASS_PUT_STR(redis); + CLASS_PUT_STR(regexp); + CLASS_PUT_STR(resolver); + CLASS_PUT_STR(rsa_privkey); + CLASS_PUT_STR(rsa_pubkey); + CLASS_PUT_STR(rsa_signature); + CLASS_PUT_STR(session); + CLASS_PUT_STR(spf_record); + CLASS_PUT_STR(sqlite3_stmt); + CLASS_PUT_STR(sqlite3); + CLASS_PUT_STR(statfile); + CLASS_PUT_STR(task); + CLASS_PUT_STR(tcp_sync); + CLASS_PUT_STR(tcp); + CLASS_PUT_STR(tensor); + CLASS_PUT_STR(textpart); + CLASS_PUT_STR(text); + CLASS_PUT_STR(trie); + CLASS_PUT_STR(upstream_list); + CLASS_PUT_STR(upstream); + CLASS_PUT_STR(url); + CLASS_PUT_STR(worker); + CLASS_PUT_STR(zstd_compress); + CLASS_PUT_STR(zstd_decompress); + + /* Check consistency */ + g_assert(kh_size(lua_static_classes) == RSPAMD_MAX_LUA_CLASSES); +} + +const char * +rspamd_lua_static_classname(const char *name, guint len) +{ + khiter_t k; + + g_assert(lua_static_classes != NULL); + char classbuf[128]; + + rspamd_strlcpy(classbuf, name, MIN(sizeof(classbuf), len + 1)); + name = classbuf; + + k = kh_get(rspamd_lua_static_classes, lua_static_classes, name); + + if (k != kh_end(lua_static_classes)) { + return kh_value(lua_static_classes, k); + } + + return NULL; +} + +RSPAMD_DESTRUCTOR(rspamd_lua_deinit_classnames) +{ + if (lua_static_classes != NULL) { + kh_destroy(rspamd_lua_static_classes, lua_static_classes); + } +} \ No newline at end of file diff --git a/src/lua/lua_classnames.h b/src/lua/lua_classnames.h index 9af339a4a..2563249b5 100644 --- a/src/lua/lua_classnames.h +++ b/src/lua/lua_classnames.h @@ -71,4 +71,12 @@ extern const char *rspamd_worker_classname; extern const char *rspamd_zstd_compress_classname; extern const char *rspamd_zstd_decompress_classname; +/* Keep it consistent when adding new classes */ +#define RSPAMD_MAX_LUA_CLASSES 48 + +/* + * Return a static class name for a given name (only for known classes) or NULL + */ +const char *rspamd_lua_static_classname(const char *name, guint len); + #endif//RSPAMD_LUA_CLASSNAMES_H diff --git a/src/lua/lua_common.c b/src/lua/lua_common.c index 5a2672fbc..8474ff790 100644 --- a/src/lua/lua_common.c +++ b/src/lua/lua_common.c @@ -1326,7 +1326,6 @@ rspamd_lua_parse_table_arguments(lua_State *L, gint pos, const gchar *p, *key = NULL, *end, *cls; va_list ap; gboolean required = FALSE, failed = FALSE, is_table; - gchar classbuf[128]; enum { read_key = 0, read_arg, @@ -1818,15 +1817,14 @@ rspamd_lua_parse_table_arguments(lua_State *L, gint pos, return FALSE; } - rspamd_snprintf(classbuf, sizeof(classbuf), "rspamd{%*s}", - (gint) clslen, cls); - + const char *static_cls = rspamd_lua_static_classname(cls, clslen); /* * We skip class check here for speed in non-table mode */ if (!failed && (!is_table || - rspamd_lua_check_class(L, idx, classbuf))) { + static_cls == NULL || + rspamd_lua_check_class(L, idx, static_cls))) { if (direct_userdata) { void **arg_p = (va_arg(ap, void **)); *arg_p = lua_touserdata(L, idx); @@ -1844,7 +1842,7 @@ rspamd_lua_parse_table_arguments(lua_State *L, gint pos, "invalid class for key %.*s, expected %s, got %s", (gint) keylen, key, - classbuf, + static_cls, rspamd_lua_class_tostring_buf(L, FALSE, idx)); va_end(ap); -- 2.39.5