diff options
author | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2018-11-03 13:05:19 +0000 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2018-11-03 13:05:19 +0000 |
commit | 13192285da90786a136b09f14f5d0442eb0f5680 (patch) | |
tree | 7e96392bc5f2768f2fb38d2ac94ca57874a9c76a /src/lua/lua_regexp.c | |
parent | d264b1dc674d09026135e7421f136447f44e14ca (diff) | |
download | rspamd-13192285da90786a136b09f14f5d0442eb0f5680.tar.gz rspamd-13192285da90786a136b09f14f5d0442eb0f5680.zip |
[Feature] Allow to create lua regexps from glob or plain patterns
Diffstat (limited to 'src/lua/lua_regexp.c')
-rw-r--r-- | src/lua/lua_regexp.c | 223 |
1 files changed, 178 insertions, 45 deletions
diff --git a/src/lua/lua_regexp.c b/src/lua/lua_regexp.c index e88dc1bcc..584f7d8c1 100644 --- a/src/lua/lua_regexp.c +++ b/src/lua/lua_regexp.c @@ -29,6 +29,8 @@ */ LUA_FUNCTION_DEF (regexp, create); +LUA_FUNCTION_DEF (regexp, import_glob); +LUA_FUNCTION_DEF (regexp, import_plain); LUA_FUNCTION_DEF (regexp, create_cached); LUA_FUNCTION_DEF (regexp, get_cached); LUA_FUNCTION_DEF (regexp, get_pattern); @@ -58,6 +60,8 @@ static const struct luaL_reg regexplib_m[] = { }; static const struct luaL_reg regexplib_f[] = { LUA_INTERFACE_DEF (regexp, create), + LUA_INTERFACE_DEF (regexp, import_glob), + LUA_INTERFACE_DEF (regexp, import_plain), LUA_INTERFACE_DEF (regexp, get_cached), LUA_INTERFACE_DEF (regexp, create_cached), {NULL, NULL} @@ -133,22 +137,142 @@ lua_regexp_create (lua_State *L) flags_str = luaL_checkstring (L, 2); } - re = rspamd_regexp_new (string, flags_str, &err); - if (re == NULL) { - lua_pushnil (L); - msg_info ("cannot parse regexp: %s, error: %s", - string, - err == NULL ? "undefined" : err->message); - g_error_free (err); + if (string) { + re = rspamd_regexp_new (string, flags_str, &err); + if (re == NULL) { + lua_pushnil (L); + msg_info ("cannot parse regexp: %s, error: %s", + string, + err == NULL ? "undefined" : err->message); + g_error_free (err); + } else { + new = g_malloc0 (sizeof (struct rspamd_lua_regexp)); + new->re = re; + new->re_pattern = g_strdup (string); + new->module = rspamd_lua_get_module_name (L); + pnew = lua_newuserdata (L, sizeof (struct rspamd_lua_regexp *)); + rspamd_lua_setclass (L, "rspamd{regexp}", -1); + *pnew = new; + } + } + else { + return luaL_error (L, "invalid arguments"); + } + + return 1; +} + +/*** + * @function rspamd_regexp.import_glob(glob_pattern[, flags]) + * Creates new rspamd_regexp from glob + * @param {string} pattern pattern to build regexp. + * @param {string} flags optional flags to create regular expression + * @return {regexp} regexp argument that is *not* automatically destroyed + * @example + * local regexp = require "rspamd_regexp" + * + * local re = regexp.import_glob('ab*', 'i') + */ +static int +lua_regexp_import_glob (lua_State *L) +{ + LUA_TRACE_POINT; + rspamd_regexp_t *re; + struct rspamd_lua_regexp *new, **pnew; + const gchar *string, *flags_str = NULL; + gchar *escaped; + gsize pat_len; + GError *err = NULL; + + string = luaL_checklstring (L, 1, &pat_len); + + if (lua_gettop (L) == 2) { + flags_str = luaL_checkstring (L, 2); + } + + if (string) { + escaped = rspamd_str_regexp_escape (string, pat_len, NULL, TRUE); + + re = rspamd_regexp_new (escaped, flags_str, &err); + + if (re == NULL) { + lua_pushnil (L); + msg_info ("cannot parse regexp: %s, error: %s", + string, + err == NULL ? "undefined" : err->message); + g_error_free (err); + g_free (escaped); + } + else { + new = g_malloc0 (sizeof (struct rspamd_lua_regexp)); + new->re = re; + new->re_pattern = escaped; + new->module = rspamd_lua_get_module_name (L); + pnew = lua_newuserdata (L, sizeof (struct rspamd_lua_regexp *)); + rspamd_lua_setclass (L, "rspamd{regexp}", -1); + *pnew = new; + } + } + else { + return luaL_error (L, "invalid arguments"); + } + + return 1; +} + +/*** + * @function rspamd_regexp.import_plain(plain_string[, flags]) + * Creates new rspamd_regexp from plain string (escaping specials) + * @param {string} pattern pattern to build regexp. + * @param {string} flags optional flags to create regular expression + * @return {regexp} regexp argument that is *not* automatically destroyed + * @example + * local regexp = require "rspamd_regexp" + * + * local re = regexp.import_plain('exact_string_with*', 'i') + */ +static int +lua_regexp_import_plain (lua_State *L) +{ + LUA_TRACE_POINT; + rspamd_regexp_t *re; + struct rspamd_lua_regexp *new, **pnew; + const gchar *string, *flags_str = NULL; + gchar *escaped; + gsize pat_len; + GError *err = NULL; + + string = luaL_checklstring (L, 1, &pat_len); + + if (lua_gettop (L) == 2) { + flags_str = luaL_checkstring (L, 2); + } + + if (string) { + escaped = rspamd_str_regexp_escape (string, pat_len, NULL, FALSE); + + re = rspamd_regexp_new (escaped, flags_str, &err); + + if (re == NULL) { + lua_pushnil (L); + msg_info ("cannot parse regexp: %s, error: %s", + string, + err == NULL ? "undefined" : err->message); + g_error_free (err); + g_free (escaped); + } + else { + new = g_malloc0 (sizeof (struct rspamd_lua_regexp)); + new->re = re; + new->re_pattern = escaped; + new->module = rspamd_lua_get_module_name (L); + pnew = lua_newuserdata (L, sizeof (struct rspamd_lua_regexp *)); + rspamd_lua_setclass (L, "rspamd{regexp}", -1); + *pnew = new; + } } else { - new = g_malloc0 (sizeof (struct rspamd_lua_regexp)); - new->re = re; - new->re_pattern = g_strdup (string); - new->module = rspamd_lua_get_module_name (L); - pnew = lua_newuserdata (L, sizeof (struct rspamd_lua_regexp *)); - rspamd_lua_setclass (L, "rspamd{regexp}", -1); - *pnew = new; + return luaL_error (L, "invalid arguments"); } return 1; @@ -175,19 +299,24 @@ lua_regexp_get_cached (lua_State *L) flags_str = luaL_checkstring (L, 2); } - re = rspamd_regexp_cache_query (NULL, string, flags_str); + if (string) { + re = rspamd_regexp_cache_query (NULL, string, flags_str); - if (re) { - new = g_malloc0 (sizeof (struct rspamd_lua_regexp)); - new->re = rspamd_regexp_ref (re); - new->re_pattern = g_strdup (string); - new->module = rspamd_lua_get_module_name (L); - pnew = lua_newuserdata (L, sizeof (struct rspamd_lua_regexp *)); - rspamd_lua_setclass (L, "rspamd{regexp}", -1); - *pnew = new; + if (re) { + new = g_malloc0 (sizeof (struct rspamd_lua_regexp)); + new->re = rspamd_regexp_ref (re); + new->re_pattern = g_strdup (string); + new->module = rspamd_lua_get_module_name (L); + pnew = lua_newuserdata (L, sizeof (struct rspamd_lua_regexp *)); + rspamd_lua_setclass (L, "rspamd{regexp}", -1); + *pnew = new; + } + else { + lua_pushnil (L); + } } else { - lua_pushnil (L); + return luaL_error (L, "invalid arguments"); } return 1; @@ -222,36 +351,40 @@ lua_regexp_create_cached (lua_State *L) flags_str = luaL_checkstring (L, 2); } - re = rspamd_regexp_cache_query (NULL, string, flags_str); + if (string) { + re = rspamd_regexp_cache_query (NULL, string, flags_str); - if (re) { - new = g_malloc0 (sizeof (struct rspamd_lua_regexp)); - new->re = rspamd_regexp_ref (re); - new->re_pattern = g_strdup (string); - new->module = rspamd_lua_get_module_name (L); - pnew = lua_newuserdata (L, sizeof (struct rspamd_lua_regexp *)); - - rspamd_lua_setclass (L, "rspamd{regexp}", -1); - *pnew = new; - } - else { - re = rspamd_regexp_cache_create (NULL, string, flags_str, &err); - if (re == NULL) { - lua_pushnil (L); - msg_info ("cannot parse regexp: %s, error: %s", - string, - err == NULL ? "undefined" : err->message); - g_error_free (err); - } - else { + if (re) { new = g_malloc0 (sizeof (struct rspamd_lua_regexp)); new->re = rspamd_regexp_ref (re); new->re_pattern = g_strdup (string); new->module = rspamd_lua_get_module_name (L); pnew = lua_newuserdata (L, sizeof (struct rspamd_lua_regexp *)); + rspamd_lua_setclass (L, "rspamd{regexp}", -1); *pnew = new; } + else { + re = rspamd_regexp_cache_create (NULL, string, flags_str, &err); + if (re == NULL) { + lua_pushnil (L); + msg_info ("cannot parse regexp: %s, error: %s", + string, + err == NULL ? "undefined" : err->message); + g_error_free (err); + } else { + new = g_malloc0 (sizeof (struct rspamd_lua_regexp)); + new->re = rspamd_regexp_ref (re); + new->re_pattern = g_strdup (string); + new->module = rspamd_lua_get_module_name (L); + pnew = lua_newuserdata (L, sizeof (struct rspamd_lua_regexp *)); + rspamd_lua_setclass (L, "rspamd{regexp}", -1); + *pnew = new; + } + } + } + else { + return luaL_error (L, "invalid arguments"); } return 1; |