From: Vsevolod Stakhov Date: Sun, 18 Dec 2016 14:53:13 +0000 (+0000) Subject: [Feature] Add method to create regexp from a glob pattern X-Git-Tag: 1.5.0~562 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=c31bbb9010e6261b6d1a00dabb0a65a99cf4697e;p=rspamd.git [Feature] Add method to create regexp from a glob pattern --- diff --git a/src/libutil/regexp.c b/src/libutil/regexp.c index c5a574f6f..e0f7b2340 100644 --- a/src/libutil/regexp.c +++ b/src/libutil/regexp.c @@ -1142,3 +1142,119 @@ rspamd_regexp_set_class (rspamd_regexp_t *re, gpointer re_class) return old_class; } + +rspamd_regexp_t * +rspamd_regexp_from_glob (const gchar *gl, gsize sz, GError **err) +{ + GString *out; + rspamd_regexp_t *re; + const gchar *end; + gboolean escaping = FALSE; + gint nbraces = 0; + + g_assert (gl != NULL); + + if (sz == 0) { + sz = strlen (gl); + } + + end = gl + sz; + out = g_string_sized_new (sz + 2); + g_string_append_c (out, '^'); + + while (gl < end) { + switch (*gl) { + case '*': + if (escaping) { + g_string_append (out, "\\*"); + } + else { + g_string_append (out, ".*"); + } + + escaping = FALSE; + break; + case '?': + if (escaping) { + g_string_append (out, "\\?"); + } + else { + g_string_append (out, "."); + } + + escaping = FALSE; + break; + case '.': + case '(': + case ')': + case '+': + case '|': + case '^': + case '$': + case '@': + case '%': + g_string_append_c (out, '\\'); + g_string_append_c (out, *gl); + escaping = FALSE; + break; + case '\\': + if (escaping) { + g_string_append (out, "\\\\"); + escaping = FALSE; + } + else { + escaping = TRUE; + } + break; + case '{': + if (escaping) { + g_string_append (out, "\\{"); + } + else { + g_string_append_c (out, '('); + nbraces++; + } + + escaping = FALSE; + break; + case '}': + if (nbraces > 0 && !escaping) { + g_string_append_c (out, ')'); + nbraces--; + } + else if (escaping) { + g_string_append (out, "\\}"); + } + else { + g_string_append (out, "}"); + } + + escaping = FALSE; + break; + case ',': + if (nbraces > 0 && !escaping) { + g_string_append_c (out, '|'); + } + else if (escaping) { + g_string_append (out, "\\,"); + } + else { + g_string_append_c (out, ','); + } + + break; + default: + escaping = FALSE; + g_string_append_c (out, *gl); + break; + } + + gl ++; + } + + g_string_append_c (out, '$'); + re = rspamd_regexp_new (out->str, "i", err); + g_string_free (out, TRUE); + + return re; +} diff --git a/src/libutil/regexp.h b/src/libutil/regexp.h index d130dea2b..c85276b71 100644 --- a/src/libutil/regexp.h +++ b/src/libutil/regexp.h @@ -257,4 +257,12 @@ void rspamd_regexp_library_init (void); */ void rspamd_regexp_library_finalize (void); +/** + * Create regexp from glob + * @param gl + * @param err + * @return + */ +rspamd_regexp_t *rspamd_regexp_from_glob (const gchar *gl, gsize sz, GError **err); + #endif /* REGEXP_H_ */