about summary refs log tree commit diff
path: root/decode.c
diff options
context:
space:
mode:
authorJune McEnroe <june@causal.agency>2020-04-29 19:01:10 -0400
committerJune McEnroe <june@causal.agency>2020-04-29 19:04:52 -0400
commit10d9be50e919b6e7d5814b579eeabfa617dc801e (patch)
tree8aed562716b64bb3040082456ee4f197e21dca05 /decode.c
parentFix infinite loop if exportAtom can't find a text part (diff)
downloadbubger-10d9be50e919b6e7d5814b579eeabfa617dc801e.tar.gz
bubger-10d9be50e919b6e7d5814b579eeabfa617dc801e.zip
Use a table to decode base64
Diffstat (limited to 'decode.c')
-rw-r--r--decode.c16
1 files changed, 13 insertions, 3 deletions
diff --git a/decode.c b/decode.c
index 8578c41..8fd005d 100644
--- a/decode.c
+++ b/decode.c
@@ -86,20 +86,30 @@ static void convertCharset(
 	iconv_close(conv);
 }
 
-static const char Base64[64] = {
+static const uint8_t Base64[64] = {
 	"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
 };
+static uint8_t Table64[256];
+
+static uint8_t unbase64(char ch) {
+	if (!Table64[Base64[1]]) {
+		for (size_t i = 0; i < sizeof(Base64); ++i) {
+			Table64[Base64[i]] = i;
+		}
+	}
+	return Table64[(uint8_t)ch];
+}
 
 static void decodeBase64(struct Buffer *dst, const char *src) {
 	while (src[0] && src[1] && src[2] && src[3]) {
-		if (!strchr(Base64, src[0])) {
+		if (!unbase64(src[0]) && src[0] != Base64[0]) {
 			src++;
 			continue;
 		}
 		uint32_t bits = 0;
 		for (int i = 0; i < 4; ++i) {
 			bits <<= 6;
-			bits |= strchr(Base64, src[i]) - Base64;
+			bits |= unbase64(src[i]);
 		}
 		*bufferDest(dst, 1) = bits >> 16;
 		if (src[2] != '=') *bufferDest(dst, 1) = bits >> 8;