aboutsummaryrefslogtreecommitdiffstats
path: root/src/libutil
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2016-12-18 14:53:13 +0000
committerVsevolod Stakhov <vsevolod@highsecure.ru>2016-12-18 14:53:13 +0000
commitc31bbb9010e6261b6d1a00dabb0a65a99cf4697e (patch)
treef4d2da4c7494be43b97e00b1a85487f7be55c4a7 /src/libutil
parent4c295c5e252f96cca9e30d00ad2a7e4ddcf746ff (diff)
downloadrspamd-c31bbb9010e6261b6d1a00dabb0a65a99cf4697e.tar.gz
rspamd-c31bbb9010e6261b6d1a00dabb0a65a99cf4697e.zip
[Feature] Add method to create regexp from a glob pattern
Diffstat (limited to 'src/libutil')
-rw-r--r--src/libutil/regexp.c116
-rw-r--r--src/libutil/regexp.h8
2 files changed, 124 insertions, 0 deletions
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_ */