]> git.ipfire.org Git - thirdparty/rspamd.git/commitdiff
Add caseless version of rabin-karp substring search
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Tue, 29 Dec 2015 09:47:34 +0000 (09:47 +0000)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Tue, 29 Dec 2015 09:47:34 +0000 (09:47 +0000)
src/libutil/str_util.c
src/libutil/str_util.h

index 8487e8ef2dd27835f2daee65e36350d89f11cda3..62d71dd2c9f03aaf0775dd638b0229517309d255 100644 (file)
@@ -1118,6 +1118,46 @@ rspamd_substring_search (const gchar *in, gsize inlen,
        return -1;
 }
 
+goffset
+rspamd_substring_search_caseless (const gchar *in, gsize inlen,
+               const gchar *srch, gsize srchlen)
+{
+       gint d, hash_srch, hash_in;
+       gsize i, j;
+       gchar c1, c2;
+
+       if (inlen < srchlen) {
+               return -1;
+       }
+
+       /* Preprocessing */
+       for (d = i = 1; i < srchlen; ++i) {
+               /* computes d = 2^(m-1) with the left-shift operator */
+               d = (d << 1);
+       }
+
+       for (hash_in = hash_srch = i = 0; i < srchlen; ++i) {
+               hash_srch = ((hash_srch << 1) + g_ascii_tolower (srch[i]));
+               hash_in = ((hash_in << 1) + g_ascii_tolower (in[i]));
+       }
+
+       /* Searching */
+       j = 0;
+       while (j <= inlen - srchlen) {
+
+               if (hash_srch == hash_in && g_ascii_strncasecmp (srch, in + j, srchlen) == 0) {
+                       return (goffset) j;
+               }
+
+               c1 = g_ascii_tolower (in[j]);
+               c2 = g_ascii_tolower (in[j + srchlen]);
+               hash_in = RKHASH (c1, c2, hash_in);
+               ++j;
+       }
+
+       return -1;
+}
+
 goffset
 rspamd_string_find_eoh (GString *input)
 {
index 8ea5e3fced5de7fd365458da38fca3ad9e2ced19..da794bc16b23298df8b228432c0ad8ccab24c487 100644 (file)
@@ -189,6 +189,17 @@ GString *rspamd_header_value_fold (const gchar *name,
 goffset rspamd_substring_search (const gchar *in, gsize inlen,
        const gchar *srch, gsize srchlen);
 
+/**
+ * Search for a substring `srch` in the text `in` using Karp-Rabin algorithm in caseless matter (ASCII only)
+ * @param in input
+ * @param inlen input len
+ * @param srch search string
+ * @param srchlen length of the search string
+ * @return position of the first substring match or (-1) if not found
+ */
+goffset rspamd_substring_search_caseless (const gchar *in, gsize inlen,
+               const gchar *srch, gsize srchlen);
+
 
 /**
  * Search for end-of-headers mark in the input string. Returns position just after