Move base64 to string.c

master
Curtis McEnroe 2018-12-16 16:21:58 -05:00
parent a2a6ce99c0
commit 38b4a53d57
No known key found for this signature in database
GPG Key ID: CEA2F97ADCFCD77C
7 changed files with 84 additions and 64 deletions

View File

@ -23,6 +23,7 @@ OBJS += input.o
OBJS += irc.o
OBJS += log.o
OBJS += pls.o
OBJS += string.o
OBJS += tab.o
OBJS += tag.o
OBJS += term.o
@ -30,7 +31,7 @@ OBJS += ui.o
OBJS += url.o
TESTS += format.t
TESTS += pls.t
TESTS += string.t
TESTS += term.t
all: tags $(BINS) test

1
README
View File

@ -31,6 +31,7 @@ FILES
edit.c line editing
tab.c tab-complete
url.c URL detection
string.c base64 and rot13
pls.c functions which should not have to be written
sandman.m utility for Darwin to signal sleep

View File

@ -66,6 +66,8 @@ line editing
tab-complete
.It Pa url.c
URL detection
.It Pa string.c
base64 and rot13
.It Pa pls.c
functions which should not have to be written
.It Pa sandman.m

4
chat.h
View File

@ -190,6 +190,9 @@ void logFmt(
) __attribute__((format(printf, 3, 4)));
void logReplay(struct Tag tag);
size_t base64Size(size_t len);
void base64(char *dst, const byte *src, size_t len);
wchar_t *wcsnchr(const wchar_t *wcs, size_t len, wchar_t chr);
wchar_t *wcsnrchr(const wchar_t *wcs, size_t len, wchar_t chr);
wchar_t *ambstowcs(const char *src);
@ -197,7 +200,6 @@ char *awcstombs(const wchar_t *src);
char *awcsntombs(const wchar_t *src, size_t nwc);
int vaswprintf(wchar_t **ret, const wchar_t *format, va_list ap);
int aswprintf(wchar_t **ret, const wchar_t *format, ...);
char *base64(const byte *src, size_t len);
// HACK: clang won't check wchar_t *format strings.
#ifdef NDEBUG

View File

@ -115,10 +115,10 @@ static void handleCap(char *prefix, char *params) {
for (size_t i = 0; i < len; ++i) {
plain[1 + i] = (self.auth[i] == ':' ? 0 : self.auth[i]);
}
char *b64 = base64(plain, sizeof(plain));
char b64[base64Size(sizeof(plain))];
base64(b64, plain, sizeof(plain));
ircFmt("AUTHENTICATE PLAIN\r\n");
ircFmt("AUTHENTICATE %s\r\n", b64);
free(b64);
}
ircFmt("CAP END\r\n");
}

60
pls.c
View File

@ -131,63 +131,3 @@ int aswprintf(wchar_t **ret, const wchar_t *format, ...) {
va_end(ap);
return n;
}
static const char Base64[64] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
char *base64(const byte *src, size_t len) {
char *dst = malloc(1 + 4 * (len + 2) / 3);
if (!dst) return NULL;
size_t i = 0;
while (len > 2) {
dst[i++] = Base64[0x3F & (src[0] >> 2)];
dst[i++] = Base64[0x3F & (src[0] << 4 | src[1] >> 4)];
dst[i++] = Base64[0x3F & (src[1] << 2 | src[2] >> 6)];
dst[i++] = Base64[0x3F & src[2]];
src += 3;
len -= 3;
}
if (len) {
dst[i++] = Base64[0x3F & (src[0] >> 2)];
if (len > 1) {
dst[i++] = Base64[0x3F & (src[0] << 4 | src[1] >> 4)];
dst[i++] = Base64[0x3F & (src[1] << 2)];
} else {
dst[i++] = Base64[0x3F & (src[0] << 4)];
dst[i++] = '=';
}
dst[i++] = '=';
}
dst[i] = '\0';
return dst;
}
#ifdef TEST
#include <assert.h>
#include <string.h>
int main() {
char *cat = base64((byte *)"cat", 3);
char *ca = base64((byte *)"ca", 2);
char *c = base64((byte *)"c", 1);
assert(cat);
assert(ca);
assert(c);
assert(!strcmp("Y2F0", cat));
assert(!strcmp("Y2E=", ca));
assert(!strcmp("Yw==", c));
free(cat);
free(ca);
free(c);
char *fzf = base64((byte []) { 0xFF, 0x00, 0xFF }, 3);
char *zfz = base64((byte []) { 0x00, 0xFF, 0x00 }, 3);
assert(fzf);
assert(zfz);
assert(!strcmp("/wD/", fzf));
assert(!strcmp("AP8A", zfz));
free(fzf);
free(zfz);
}
#endif

74
string.c 100644
View File

@ -0,0 +1,74 @@
/* Copyright (C) 2018 C. McEnroe <june@causal.agency>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <err.h>
#include <stdlib.h>
#include <string.h>
#include <sysexits.h>
#include "chat.h"
static const char Base64[64] = {
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
};
size_t base64Size(size_t len) {
return 1 + (len + 2) / 3 * 4;
}
void base64(char *dst, const byte *src, size_t len) {
size_t i = 0;
while (len > 2) {
dst[i++] = Base64[0x3F & (src[0] >> 2)];
dst[i++] = Base64[0x3F & (src[0] << 4 | src[1] >> 4)];
dst[i++] = Base64[0x3F & (src[1] << 2 | src[2] >> 6)];
dst[i++] = Base64[0x3F & src[2]];
src += 3;
len -= 3;
}
if (len) {
dst[i++] = Base64[0x3F & (src[0] >> 2)];
if (len > 1) {
dst[i++] = Base64[0x3F & (src[0] << 4 | src[1] >> 4)];
dst[i++] = Base64[0x3F & (src[1] << 2)];
} else {
dst[i++] = Base64[0x3F & (src[0] << 4)];
dst[i++] = '=';
}
dst[i++] = '=';
}
dst[i] = '\0';
}
#ifdef TEST
#include <assert.h>
int main() {
assert(5 == base64Size(1));
assert(5 == base64Size(2));
assert(5 == base64Size(3));
assert(9 == base64Size(4));
char b64[base64Size(3)];
assert((base64(b64, (byte *)"cat", 3), !strcmp("Y2F0", b64)));
assert((base64(b64, (byte *)"ca", 2), !strcmp("Y2E=", b64)));
assert((base64(b64, (byte *)"c", 1), !strcmp("Yw==", b64)));
assert((base64(b64, (byte *)"\xFF\x00\xFF", 3), !strcmp("/wD/", b64)));
assert((base64(b64, (byte *)"\x00\xFF\x00", 3), !strcmp("AP8A", b64)));
}
#endif