aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMiecio Za <miecio@miecio.net>2019-03-18 14:06:56 +0100
committerMiecio Za <miecio@miecio.net>2019-03-18 14:06:56 +0100
commitcd08c8845f6ea0bac789ea8a49f7d8537f598b7d (patch)
treedee0d9dbc67008cd190c502393098c5f2772a764 /src
parent7160b4ace6665d808b636b0617f081f51a849617 (diff)
downloadrspamd-cd08c8845f6ea0bac789ea8a49f7d8537f598b7d.tar.gz
rspamd-cd08c8845f6ea0bac789ea8a49f7d8537f598b7d.zip
[Minor] Fix performance issue with is_utf_outside_range
Fix performace issue, add some checking and add few tests
Diffstat (limited to 'src')
-rw-r--r--src/lua/lua_util.c67
1 files changed, 49 insertions, 18 deletions
diff --git a/src/lua/lua_util.c b/src/lua/lua_util.c
index 71d61da62..7c98a0989 100644
--- a/src/lua/lua_util.c
+++ b/src/lua/lua_util.c
@@ -22,6 +22,7 @@
#include "libmime/email_addr.h"
#include "libmime/content_type.h"
#include "libmime/mime_headers.h"
+#include "libutil/hash.h"
#include "linenoise.h"
#include <math.h>
#include <glob.h>
@@ -2458,6 +2459,12 @@ lua_util_is_utf_spoofed (lua_State *L)
uspoof_setChecks (spc_sgl,
USPOOF_INVISIBLE | USPOOF_MIXED_SCRIPT_CONFUSABLE | USPOOF_ANY_CASE,
&uc_err);
+ if (uc_err != U_ZERO_ERROR) {
+ msg_err ("Cannot set proper checks for uspoof: %s", u_errorName (uc_err));
+ lua_pushboolean (L, false);
+ uspoof_close(spc);
+ return 1;
+ }
}
ret = uspoof_checkUTF8 (spc_sgl, s1, l1, NULL, &uc_err);
@@ -2533,28 +2540,52 @@ lua_util_is_utf_outside_range(lua_State *L)
guint32 range_start = lua_tointeger (L, 2);
guint32 range_end = lua_tointeger (L, 3);
- USpoofChecker *spc_sgl;
- USet * allowed_chars;
- UErrorCode uc_err = U_ZERO_ERROR;
+ static rspamd_lru_hash_t *validators;
+
+ if (validators == NULL) {
+ validators = rspamd_lru_hash_new(16, g_free, (GDestroyNotify)uspoof_close);
+ }
if (string_to_check) {
- spc_sgl = uspoof_open (&uc_err);
- if (uc_err != U_ZERO_ERROR) {
- msg_err ("cannot init spoof checker: %s", u_errorName (uc_err));
- lua_pushboolean (L, false);
- uspoof_close(spc_sgl);
- return 1;
- }
+ guint64 hash_key = (guint64)range_end << 32 || range_start;
+
+ USpoofChecker *validator = rspamd_lru_hash_lookup(validators, &hash_key, time(NULL));
+
+ UErrorCode uc_err = U_ZERO_ERROR;
+
+ if (validator == NULL) {
+ USet * allowed_chars;
+ guint64 * creation_hash_key = g_malloc(sizeof(guint64));
+ *creation_hash_key = hash_key;
+
+ validator = uspoof_open (&uc_err);
+ if (uc_err != U_ZERO_ERROR) {
+ msg_err ("cannot init spoof checker: %s", u_errorName (uc_err));
+ lua_pushboolean (L, false);
+ uspoof_close(validator);
+ return 1;
+ }
+
+ allowed_chars = uset_openEmpty();
+ uset_addRange(allowed_chars, range_start, range_end);
+ uspoof_setAllowedChars(validator, allowed_chars, &uc_err);
+
+ uspoof_setChecks (validator,
+ USPOOF_CHAR_LIMIT | USPOOF_ANY_CASE, &uc_err);
- allowed_chars = uset_openEmpty();
- uset_addRange(allowed_chars, range_start, range_end);
- uspoof_setAllowedChars(spc_sgl, allowed_chars, &uc_err);
+ uset_close(allowed_chars);
+
+ if (uc_err != U_ZERO_ERROR) {
+ msg_err ("Cannot configure uspoof: %s", u_errorName (uc_err));
+ lua_pushboolean (L, false);
+ uspoof_close(validator);
+ return 1;
+ }
+
+ rspamd_lru_hash_insert(validators, creation_hash_key, validator, time(NULL), 0);
+ }
- uspoof_setChecks (spc_sgl,
- USPOOF_CHAR_LIMIT | USPOOF_ANY_CASE, &uc_err);
- ret = uspoof_checkUTF8 (spc_sgl, string_to_check, len_of_string, NULL, &uc_err);
- uset_close(allowed_chars);
- uspoof_close(spc_sgl);
+ ret = uspoof_checkUTF8 (validator, string_to_check, len_of_string, NULL, &uc_err);
}
else {
return luaL_error (L, "invalid arguments");