roken: Fix base32/64 decode slowness

This commit is contained in:
Nicolas Williams
2023-01-03 20:19:47 -06:00
parent 7c3a064764
commit 11c0cbe9c2
2 changed files with 21 additions and 11 deletions

View File

@@ -141,9 +141,7 @@ token_decode(const char *token, enum rk_base32_flags flags)
int preserve_order = !!(flags & RK_BASE32_FLAG_PRESERVE_ORDER); int preserve_order = !!(flags & RK_BASE32_FLAG_PRESERVE_ORDER);
int i, c; int i, c;
if (strlen(token) < 8) for (i = 0; i < 8 && token[i] != '\0'; i++) {
return DECODE_ERROR;
for (i = 0; i < 8; i++) {
val <<= 5; val <<= 5;
if (token[i] == '=') if (token[i] == '=')
marker++; marker++;
@@ -157,7 +155,7 @@ token_decode(const char *token, enum rk_base32_flags flags)
else else
val |= c; val |= c;
} }
if (marker > 6) if (i < 8 || marker > 6)
return DECODE_ERROR; return DECODE_ERROR;
return (marker << 40) | val; return (marker << 40) | val;
} }

View File

@@ -45,17 +45,31 @@
#include "base64.h" #include "base64.h"
#include "roken.h" #include "roken.h"
static const char base64_chars[] = #define base64_chars "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static int static int
pos(char c) pos(char c)
{ {
#if 'A' == '\301'
const char *p; const char *p;
for (p = base64_chars; *p; p++) for (p = base64_chars; *p; p++)
if (*p == c) if (*p == c)
return p - base64_chars; return p - base64_chars;
return -1; return -1;
#else
if (c >= 'A' && c <= 'Z')
return c - 'A';
if (c >= 'a' && c <= 'z')
return ('Z' + 1 - 'A') + c - 'a';
if (c >= '0' && c <= '9')
return ('Z' + 1 - 'A') +
('z' + 1 - 'a') + c - '0';
if (c == '+')
return 62;
if (c == '/')
return 63;
return -1;
#endif
} }
ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL
@@ -112,9 +126,7 @@ token_decode(const char *token)
int i; int i;
unsigned int val = 0; unsigned int val = 0;
int marker = 0; int marker = 0;
if (strlen(token) < 4) for (i = 0; i < 4 && token[i] != '\0'; i++) {
return DECODE_ERROR;
for (i = 0; i < 4; i++) {
val *= 64; val *= 64;
if (token[i] == '=') if (token[i] == '=')
marker++; marker++;
@@ -123,7 +135,7 @@ token_decode(const char *token)
else else
val += pos(token[i]); val += pos(token[i]);
} }
if (marker > 2) if (i < 4 || marker > 2)
return DECODE_ERROR; return DECODE_ERROR;
return (marker << 24) | val; return (marker << 24) | val;
} }
@@ -135,7 +147,7 @@ rk_base64_decode(const char *str, void *data)
unsigned char *q; unsigned char *q;
q = data; q = data;
for (p = str; *p && (*p == '=' || strchr(base64_chars, *p)); p += 4) { for (p = str; *p && (*p == '=' || pos(*p) != -1); p += 4) {
unsigned int val = token_decode(p); unsigned int val = token_decode(p);
unsigned int marker = (val >> 24) & 0xff; unsigned int marker = (val >> 24) & 0xff;
if (val == DECODE_ERROR) { if (val == DECODE_ERROR) {