/* Process regexp expression */ static gboolean read_regexp_expression (rspamd_mempool_t * pool, struct regexp_module_item *chain, const gchar *symbol, const gchar *line, struct rspamd_config *cfg) { struct rspamd_expression *e = NULL; GError *err = NULL; if (!rspamd_parse_expression (line, 0, &mime_expr_subr, cfg, pool, &err, &e)) { msg_warn_pool ("%s = \"%s\" is invalid regexp expression: %e", symbol, line, err); g_error_free (err); return FALSE; } g_assert (e != NULL); chain->expr = e; return TRUE; }
static gint lua_expr_create (lua_State *L) { struct lua_expression *e, **pe; const char *line; gsize len; GError *err = NULL; rspamd_mempool_t *pool; /* Check sanity of the arguments */ if (lua_type (L, 1) != LUA_TSTRING || lua_type (L, 2) != LUA_TTABLE || rspamd_lua_check_mempool (L, 3) == NULL) { msg_info ("bad arguments to lua_expr_create"); lua_pushnil (L); lua_pushstring (L, "bad arguments"); } else { line = lua_tolstring (L, 1, &len); pool = rspamd_lua_check_mempool (L, 3); /* Check callbacks */ lua_pushvalue (L, 2); lua_pushnumber (L, 1); lua_gettable (L, -2); if (lua_type (L, -1) != LUA_TFUNCTION) { lua_pop (L, 2); lua_pushnil (L); lua_pushstring (L, "bad parse callback"); return 2; } lua_pop (L, 1); lua_pushnumber (L, 2); lua_gettable (L, -2); if (lua_type (L, -1) != LUA_TFUNCTION) { lua_pop (L, 2); lua_pushnil (L); lua_pushstring (L, "bad process callback"); return 2; } lua_pop (L, 1); /* Table is still on the top of stack */ e = rspamd_mempool_alloc (pool, sizeof (*e)); e->L = L; e->pool = pool; lua_pushnumber (L, 1); lua_gettable (L, -2); e->parse_idx = luaL_ref (L, LUA_REGISTRYINDEX); lua_pushnumber (L, 2); lua_gettable (L, -2); e->process_idx = luaL_ref (L, LUA_REGISTRYINDEX); lua_pop (L, 1); /* Table */ if (!rspamd_parse_expression (line, len, &lua_atom_subr, e, pool, &err, &e->expr)) { lua_pushnil (L); lua_pushstring (L, err->message); g_error_free (err); return 2; } pe = lua_newuserdata (L, sizeof (struct lua_expression *)); rspamd_lua_setclass (L, "rspamd{expr}", -1); *pe = e; lua_pushnil (L); } return 2; }
/* Do post load initialization based on lua */ void rspamd_lua_post_load_config (struct rspamd_config *cfg) { lua_State *L = cfg->lua_state; const gchar *name, *val; gchar *sym; struct rspamd_expression *expr, *old_expr; ucl_object_t *obj; gsize keylen; GError *err = NULL; /* First check all module options that may be overriden in 'config' global */ lua_getglobal (L, "config"); if (lua_istable (L, -1)) { /* Iterate */ for (lua_pushnil (L); lua_next (L, -2); lua_pop (L, 1)) { /* 'key' is at index -2 and 'value' is at index -1 */ /* Key must be a string and value must be a table */ name = luaL_checklstring (L, -2, &keylen); if (name != NULL && lua_istable (L, -1)) { obj = ucl_object_lua_import (L, lua_gettop (L)); if (obj != NULL) { ucl_object_insert_key_merged (cfg->rcl_obj, obj, name, keylen, true); } } } } /* Check metrics settings */ lua_getglobal (L, "metrics"); if (lua_istable (L, -1)) { /* Iterate */ for (lua_pushnil (L); lua_next (L, -2); lua_pop (L, 1)) { /* 'key' is at index -2 and 'value' is at index -1 */ /* Key must be a string and value must be a table */ name = luaL_checkstring (L, -2); if (name != NULL && lua_istable (L, -1)) { lua_process_metric (L, name, cfg); } } } /* Check composites */ lua_getglobal (L, "composites"); if (lua_istable (L, -1)) { /* Iterate */ for (lua_pushnil (L); lua_next (L, -2); lua_pop (L, 1)) { /* 'key' is at index -2 and 'value' is at index -1 */ /* Key must be a string and value must be a table */ name = luaL_checkstring (L, -2); if (name != NULL && lua_isstring (L, -1)) { val = lua_tostring (L, -1); sym = rspamd_mempool_strdup (cfg->cfg_pool, name); if (!rspamd_parse_expression (val, 0, &composite_expr_subr, NULL, cfg->cfg_pool, &err, &expr)) { msg_err_config("cannot parse composite expression '%s': %s", val, err->message); g_error_free (err); err = NULL; continue; } /* Now check hash table for this composite */ if ((old_expr = g_hash_table_lookup (cfg->composite_symbols, name)) != NULL) { msg_info_config("replacing composite symbol %s", name); g_hash_table_replace (cfg->composite_symbols, sym, expr); } else { g_hash_table_insert (cfg->composite_symbols, sym, expr); rspamd_symbols_cache_add_symbol (cfg->cache, sym, 0, NULL, NULL, SYMBOL_TYPE_COMPOSITE, -1); } } } } }
static gint lua_expr_create (lua_State *L) { LUA_TRACE_POINT; struct lua_expression *e, **pe; const char *line; gsize len; gboolean no_process = FALSE; GError *err = NULL; rspamd_mempool_t *pool; /* Check sanity of the arguments */ if (lua_type (L, 1) != LUA_TSTRING || (lua_type (L, 2) != LUA_TTABLE && lua_type (L, 2) != LUA_TFUNCTION) || rspamd_lua_check_mempool (L, 3) == NULL) { msg_info ("bad arguments to lua_expr_create"); lua_pushnil (L); lua_pushstring (L, "bad arguments"); } else { line = lua_tolstring (L, 1, &len); pool = rspamd_lua_check_mempool (L, 3); e = rspamd_mempool_alloc (pool, sizeof (*e)); e->L = L; e->pool = pool; /* Check callbacks */ if (lua_istable (L, 2)) { lua_pushvalue (L, 2); lua_pushnumber (L, 1); lua_gettable (L, -2); if (lua_type (L, -1) != LUA_TFUNCTION) { lua_pop (L, 2); lua_pushnil (L); lua_pushstring (L, "bad parse callback"); return 2; } lua_pop (L, 1); lua_pushnumber (L, 2); lua_gettable (L, -2); if (lua_type (L, -1) != LUA_TFUNCTION) { if (lua_type (L, -1) != LUA_TNIL && lua_type (L, -1) != LUA_TNONE) { lua_pop (L, 2); lua_pushnil (L); lua_pushstring (L, "bad process callback"); return 2; } else { no_process = TRUE; } } lua_pop (L, 1); /* Table is still on the top of stack */ lua_pushnumber (L, 1); lua_gettable (L, -2); e->parse_idx = luaL_ref (L, LUA_REGISTRYINDEX); if (!no_process) { lua_pushnumber (L, 2); lua_gettable (L, -2); e->process_idx = luaL_ref (L, LUA_REGISTRYINDEX); } else { e->process_idx = -1; } lua_pop (L, 1); /* Table */ } else { /* Process function is just a function, not a table */ lua_pushvalue (L, 2); e->parse_idx = luaL_ref (L, LUA_REGISTRYINDEX); e->process_idx = -1; } if (!rspamd_parse_expression (line, len, &lua_atom_subr, e, pool, &err, &e->expr)) { lua_pushnil (L); lua_pushstring (L, err->message); g_error_free (err); lua_expr_dtor (e); return 2; } rspamd_mempool_add_destructor (pool, lua_expr_dtor, e); pe = lua_newuserdata (L, sizeof (struct lua_expression *)); rspamd_lua_setclass (L, "rspamd{expr}", -1); *pe = e; lua_pushnil (L); } return 2; }