diff options
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | libar2.h | 1 | ||||
-rw-r--r-- | libar2_encode_base64.3 | 21 | ||||
-rw-r--r-- | libar2_encode_base64.c | 37 | ||||
-rw-r--r-- | test.c | 28 |
5 files changed, 71 insertions, 18 deletions
@@ -80,6 +80,7 @@ install: libar2.a libar2.$(LIBEXT) cp -- libar2.h "$(DESTDIR)$(PREFIX)/include/" cp -- $(MAN3) "$(DESTDIR)$(MANPREFIX)/man3/" cp -- $(MAN7) "$(DESTDIR)$(MANPREFIX)/man7/" + ln -sf -- libar2_encode_base64.3 "$(DESTDIR)$(MANPREFIX)/man3/libar2_encode_base64_overlap_support.3" uninstall: -rm -f -- "$(DESTDIR)$(PREFIX)/lib/libar2.a" @@ -89,6 +90,7 @@ uninstall: -rm -f -- "$(DESTDIR)$(PREFIX)/include/libar2.h" -cd -- "$(DESTDIR)$(MANPREFIX)/man3/" && rm -f -- $(MAN3) -cd -- "$(DESTDIR)$(MANPREFIX)/man7/" && rm -f -- $(MAN7) + -rm -f -- "$(DESTDIR)$(MANPREFIX)/man3/libar2_encode_base64_overlap_support.3" clean: -rm -f -- *.o *.a *.lo *.su *.so *.so.* *.dll *.dylib @@ -552,6 +552,7 @@ size_t libar2_encode_params(char *buf, const struct libar2_argon2_parameters *pa */ LIBAR2_PUBLIC__ size_t libar2_encode_base64(char *buf, const void *data, size_t len); +#define libar2_encode_base64_overlap_support libar2_encode_base64 /** * Decode hashing parameters diff --git a/libar2_encode_base64.3 b/libar2_encode_base64.3 index 89abaa7..c40e002 100644 --- a/libar2_encode_base64.3 +++ b/libar2_encode_base64.3 @@ -7,6 +7,8 @@ libar2_encode_base64 - Encode data to base64 #include <libar2.h> size_t libar2_encode_base64(char *\fIbuf\fP, const void *\fIdata\fP, size_t \fIlen\fP); + +#define libar2_encode_base64_overlap_support libar2_encode_base64 .fi .PP Link with @@ -47,6 +49,25 @@ is 0 or if is .IR NULL . +.PP +In previous versions of libar2, the +.BR libar2_encode_base64 (3) +did not support overlap in the +.I buf +and +.IR data , +this was a bug. The existence of the +.B libar2_encode_base64_overlap_support +macro indicates that this bug has been fixed. +The +.B libar2_encode_base64_overlap_support +macro is defined as +.I libar2_encode_base64 +so that it can be used in place of +.BR libar2_encode_base64 () +if support of memory overlap is required; e.g. +when encoding directly into the read buffer. + .SH RETURN VALUES The .BR libar2_encode_base64 () diff --git a/libar2_encode_base64.c b/libar2_encode_base64.c index 857b3e8..f9507e9 100644 --- a/libar2_encode_base64.c +++ b/libar2_encode_base64.c @@ -15,27 +15,40 @@ size_t libar2_encode_base64(char *buf, const void *data_, size_t len) { const unsigned char *data = data_; + unsigned char a, b, c; size_t q, r, i; q = len / 3; r = len % 3; if (buf) { - for (i = 0; i < q; i++, data += 3) { - *buf++ = lut[O1(data[0], data[1], data[2]) & 255]; - *buf++ = lut[O2(data[0], data[1], data[2]) & 255]; - *buf++ = lut[O3(data[0], data[1], data[2]) & 255]; - *buf++ = lut[O4(data[0], data[1], data[2]) & 255]; - } + buf = &buf[q * 4]; + data = &data[q * 3]; + if (r == 1) { - *buf++ = lut[O1(data[0], 0, 0) & 255]; - *buf++ = lut[O2(data[0], 0, 0) & 255]; + a = data[0]; + buf[0] = lut[O1(a, 0, 0) & 255]; + buf[1] = lut[O2(a, 0, 0) & 255]; + buf[2] = '\0'; } else if (r == 2) { - *buf++ = lut[O1(data[0], data[1], 0) & 255]; - *buf++ = lut[O2(data[0], data[1], 0) & 255]; - *buf++ = lut[O3(data[0], data[1], 0) & 255]; + a = data[0], b = data[1]; + buf[0] = lut[O1(a, b, 0) & 255]; + buf[1] = lut[O2(a, b, 0) & 255]; + buf[2] = lut[O3(a, b, 0) & 255]; + buf[3] = '\0'; + } else { + buf[0] = '\0'; + } + + for (i = 0; i < q; i++) { + data -= 3; + buf -= 4; + a = data[0], b = data[1], c = data[2]; + buf[0] = lut[O1(a, b, c) & 255]; + buf[1] = lut[O2(a, b, c) & 255]; + buf[2] = lut[O3(a, b, c) & 255]; + buf[3] = lut[O4(a, b, c) & 255]; } - *buf = '\0'; } return (q * 4) + r + !!r + 1; @@ -555,33 +555,49 @@ check_libar2_encode_base64(void) assert_streq(buf, ""); assert(errno == 0); - assert(libar2_encode_base64(buf, MEM("\x00")) == 3); +#define ENCODE_BASE64(S) libar2_encode_base64(buf, MEM(S)) + + assert(ENCODE_BASE64("") == 1); + assert_streq(buf, ""); + assert(errno == 0); + + assert(ENCODE_BASE64("\x00") == 3); assert_streq(buf, "AA"); assert(errno == 0); - assert(libar2_encode_base64(buf, MEM("\x00\x00")) == 4); + assert(ENCODE_BASE64("\x00\x00") == 4); assert_streq(buf, "AAA"); assert(errno == 0); - assert(libar2_encode_base64(buf, MEM("\x00\x00\x00")) == 5); + assert(ENCODE_BASE64("\x00\x00\x00") == 5); assert_streq(buf, "AAAA"); assert(errno == 0); - assert(libar2_encode_base64(buf, MEM("12345678")) == 12); + assert(ENCODE_BASE64("12345678") == 12); assert_streq(buf, "MTIzNDU2Nzg"); assert(errno == 0); - assert(libar2_encode_base64(buf, MEM("testtest")) == 12); + assert(ENCODE_BASE64("testtest") == 12); assert_streq(buf, "dGVzdHRlc3Q"); assert(errno == 0); - assert(libar2_encode_base64(buf, MEM("zy[]y21 !")) == 13); + assert(ENCODE_BASE64("zy[]y21 !") == 13); assert_streq(buf, "enlbXXkyMSAh"); assert(errno == 0); + assert(ENCODE_BASE64("{~|~}~~~\x7f\x7f") == 15); + assert_streq(buf, "e358fn1+fn5/fw"); + assert(errno == 0); + +#undef ENCODE_BASE64 + assert(libar2_encode_base64(buf, MEM("{~|~}~~~\x7f\x7f")) == 15); assert_streq(buf, "e358fn1+fn5/fw"); assert(errno == 0); + + assert(libar2_encode_base64_overlap_support(buf, MEM("{~|~}~~~\x7f\x7f")) == 15); + assert_streq(buf, "e358fn1+fn5/fw"); + assert(errno == 0); } |