]> source.dussan.org Git - rspamd.git/commitdiff
[Feature] Performance: Do not use base64 SIMD version for bad inputs
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Thu, 25 Jul 2019 13:53:49 +0000 (14:53 +0100)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Thu, 25 Jul 2019 13:53:49 +0000 (14:53 +0100)
src/libcryptobox/base64/base64.c

index eccc89a742321f5c593a391ca144781205683d7c..03ca99786281b425e89a2e4c92f0ee9119eeb759 100644 (file)
@@ -43,6 +43,8 @@ base64_table_dec[256] =
        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
 };
 
+static const char base64_alphabet[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/";
+
 typedef struct base64_impl {
        unsigned long cpu_flags;
        const char *desc;
@@ -90,6 +92,7 @@ static const base64_impl_t base64_list[] = {
 };
 
 static const base64_impl_t *base64_opt = &base64_list[0];
+static const base64_impl_t *base64_ref = &base64_list[0];
 
 const char *
 base64_load (void)
@@ -113,7 +116,27 @@ gboolean
 rspamd_cryptobox_base64_decode (const gchar *in, gsize inlen,
                guchar *out, gsize *outlen)
 {
-       return base64_opt->decode (in, inlen, out, outlen);
+       if (inlen > 256) {
+               /*
+                * For SIMD base64 decoding we need really large inputs with no
+                * garbadge such as newlines
+                * Otherwise, naive version is MUCH faster
+                */
+
+               if (rspamd_memcspn (in, base64_alphabet, 256) == 256) {
+                       return base64_opt->decode (in, inlen, out, outlen);
+               }
+               else {
+                       /* Garbage found */
+                       return base64_ref->decode (in, inlen, out, outlen);
+               }
+       }
+       else {
+               /* Small input, use reference version */
+               return base64_ref->decode (in, inlen, out, outlen);
+       }
+
+       g_assert_not_reached ();
 }
 
 size_t