commit fcc55453c7f6db042c9b63f981154090ee1cf45a
parent 8215277483ff989520eeb6d4ccec424b795a632e
Author: Joris Vink <joris@coders.se>
Date: Mon, 24 Jul 2017 08:19:03 +0200
massively simplify base64 encoding.
Diffstat:
2 files changed, 55 insertions(+), 56 deletions(-)
diff --git a/includes/kore.h b/includes/kore.h
@@ -577,7 +577,7 @@ int kore_split_string(char *, const char *, char **, size_t);
void kore_strip_chars(char *, const char, char **);
int kore_snprintf(char *, size_t, int *, const char *, ...);
long long kore_strtonum(const char *, int, long long, long long, int *);
-int kore_base64_encode(u_int8_t *, size_t, char **);
+int kore_base64_encode(const void *, size_t, char **);
int kore_base64_decode(char *, u_int8_t **, size_t *);
void *kore_mem_find(void *, size_t, void *, size_t);
char *kore_text_trim(char *, size_t);
diff --git a/src/utils.c b/src/utils.c
@@ -377,68 +377,67 @@ kore_time_ms(void)
}
int
-kore_base64_encode(u_int8_t *data, size_t len, char **out)
+kore_base64_encode(const void *data, size_t len, char **out)
{
- u_int32_t b;
- struct kore_buf *res;
- size_t plen, idx;
- u_int8_t n, *pdata;
- int i, padding;
-
- if ((len % 3) != 0) {
- padding = 3 - (len % 3);
- plen = len + padding;
- if (plen < len)
- fatal("plen wrapped");
-
- pdata = kore_malloc(plen);
- memcpy(pdata, data, len);
- memset(pdata + len, 0, padding);
- } else {
- plen = len;
- padding = 0;
- pdata = data;
- }
-
- res = kore_buf_alloc(plen);
+ u_int8_t n;
+ size_t nb;
+ const u_int8_t *ptr;
+ u_int32_t bytes;
+ struct kore_buf result;
+
+ ptr = data;
+ kore_buf_init(&result, (len / 3) * 4);
+
+ while (len > 0) {
+ if (len > 2) {
+ nb = 3;
+ bytes = *ptr++ << 16;
+ bytes |= *ptr++ << 8;
+ bytes |= *ptr++;
+ } else if (len > 1) {
+ nb = 2;
+ bytes = *ptr++ << 16;
+ bytes |= *ptr++ << 8;
+ } else if (len == 1) {
+ nb = 1;
+ bytes = *ptr++ << 16;
+ } else {
+ kore_buf_cleanup(&result);
+ return (KORE_RESULT_ERROR);
+ }
- i = 2;
- b = 0;
- for (idx = 0; idx < plen; idx++) {
- b |= (pdata[idx] << (i * 8));
- if (i-- == 0) {
- for (i = 3; i >= 0; i--) {
- n = (b >> (6 * i)) & 0x3f;
- if (n >= sizeof(b64table)) {
- kore_debug("unable to encode %d", n);
- kore_buf_free(res);
- return (KORE_RESULT_ERROR);
- }
-
- if (idx >= len && i < padding)
- break;
-
- kore_buf_append(res, &(b64table[n]), 1);
+ n = (bytes >> 18) & 0x3f;
+ kore_buf_append(&result, &(b64table[n]), 1);
+ n = (bytes >> 12) & 0x3f;
+ kore_buf_append(&result, &(b64table[n]), 1);
+ if (nb > 1) {
+ n = (bytes >> 6) & 0x3f;
+ kore_buf_append(&result, &(b64table[n]), 1);
+ if (nb > 2) {
+ n = bytes & 0x3f;
+ kore_buf_append(&result, &(b64table[n]), 1);
}
-
- b = 0;
- i = 2;
}
- }
-
- for (i = 0; i < padding; i++)
- kore_buf_append(res, (u_int8_t *)"=", 1);
- if (pdata != data)
- kore_free(pdata);
+ len -= nb;
+ }
- pdata = kore_buf_release(res, &plen);
- if ((plen + 1) < plen)
- fatal("plen wrapped");
+ switch (nb) {
+ case 1:
+ kore_buf_appendf(&result, "==");
+ break;
+ case 2:
+ kore_buf_appendf(&result, "=");
+ break;
+ case 3:
+ break;
+ default:
+ kore_buf_cleanup(&result);
+ return (KORE_RESULT_ERROR);
+ }
- *out = kore_malloc(plen + 1);
- (void)kore_strlcpy(*out, (char *)pdata, plen + 1);
- kore_free(pdata);
+ /* result.data gets taken over so no need to cleanup result. */
+ *out = kore_buf_stringify(&result, NULL);
return (KORE_RESULT_OK);
}