aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMattias Andrée <maandree@kth.se>2022-03-19 22:33:41 +0100
committerMattias Andrée <maandree@kth.se>2022-03-19 22:33:46 +0100
commitb5508dd1088acfc31a8a92fd9798fced0bcb41b3 (patch)
tree54bea20b98ed9848727230ff994e708e35e7a87d
parenttest: check libar2_decode_base64 with buffer overlap (diff)
downloadlibar2-1.2.2.tar.gz
libar2-1.2.2.tar.bz2
libar2-1.2.2.tar.xz
libar2_encode_base64: fix support for overlap1.2.2
Signed-off-by: Mattias Andrée <maandree@kth.se>
-rw-r--r--Makefile2
-rw-r--r--libar2.h1
-rw-r--r--libar2_encode_base64.321
-rw-r--r--libar2_encode_base64.c37
-rw-r--r--test.c28
5 files changed, 71 insertions, 18 deletions
diff --git a/Makefile b/Makefile
index 029b33f..7b4f6b8 100644
--- a/Makefile
+++ b/Makefile
@@ -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
diff --git a/libar2.h b/libar2.h
index 8343a8f..dc877af 100644
--- a/libar2.h
+++ b/libar2.h
@@ -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;
diff --git a/test.c b/test.c
index 115640e..cd68011 100644
--- a/test.c
+++ b/test.c
@@ -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);
}