about summary refs log tree commit diff
path: root/rfc2047.c
diff options
context:
space:
mode:
authorChristian Neukirchen <chneukirchen@gmail.com>2016-07-14 18:24:08 +0200
committerChristian Neukirchen <chneukirchen@gmail.com>2016-07-14 18:24:08 +0200
commit00b0e23f1f00344f0b4c5b57f81ea19a7e3eaf18 (patch)
treed50b01c7e02aa341be04baa8fd9fe09edbf2aeda /rfc2047.c
parent15016ba4cac7e38ed0a99ac87c5e8e22a28a7a78 (diff)
downloadmblaze-00b0e23f1f00344f0b4c5b57f81ea19a7e3eaf18.tar.gz
mblaze-00b0e23f1f00344f0b4c5b57f81ea19a7e3eaf18.tar.xz
mblaze-00b0e23f1f00344f0b4c5b57f81ea19a7e3eaf18.zip
rfc2047: blaze822_decode_b64: check bounds
Diffstat (limited to 'rfc2047.c')
-rw-r--r--rfc2047.c53
1 files changed, 30 insertions, 23 deletions
diff --git a/rfc2047.c b/rfc2047.c
index ed39084..903078d 100644
--- a/rfc2047.c
+++ b/rfc2047.c
@@ -8,7 +8,6 @@
 #include "blaze822.h"
 #include "blaze822_priv.h"
 
-// XXX error detection on decode
 // XXX keep trying bytewise on invalid iconv
 
 int
@@ -32,8 +31,6 @@ blaze822_decode_qp(char *start, char *stop, char **deco, size_t *decleno)
 	*deco = buf;
 
 	char *s = start;
-	size_t declen;
-
 	while (s < stop) {
 		if (*s == '=' && s[1] == '\n') {
 			s += 2;
@@ -81,23 +78,33 @@ blaze822_decode_b64(char *s, char *e, char **deco, size_t *decleno)
 	while (s + 4 <= e) {
 		while (s < e && isfws((unsigned char) *s))
 			s++;
-		if (s < e) {
-			uint32_t v = 0;
-			v |= b64[s[0]]; v <<= 6;
-			v |= b64[s[1]]; v <<= 6;
-			v |= b64[s[2]]; v <<= 6;
-			v |= b64[s[3]];
-			
-			char d2 = v & 0xff; v >>= 8;
-			char d1 = v & 0xff; v >>= 8;
-			char d0 = v & 0xff;
-
-			if (s[1] != '=') *buf++ = d0;
-			if (s[2] != '=') *buf++ = d1;
-			if (s[3] != '=') *buf++ = d2;
-			
-			s += 4;
-		}
+		if (s >= e)
+			break;
+
+		uint32_t v = 0;
+		unsigned char t = 0;
+
+		unsigned char c0=s[0], c1=s[1], c2=s[2], c3=s[3];
+		s += 4;
+
+		if ((c0 | c1 | c2 | c3) > 127)
+			continue;
+
+		v |= b64[c0]; t |= b64[c0]; v <<= 6;
+		v |= b64[c1]; t |= b64[c1]; v <<= 6;
+		v |= b64[c2]; t |= b64[c2]; v <<= 6;
+		v |= b64[c3]; t |= b64[c3];
+
+		if (t > 127)
+			continue;
+
+		char d2 = v & 0xff; v >>= 8;
+		char d1 = v & 0xff; v >>= 8;
+		char d0 = v & 0xff;
+
+		if (c1 != '=') *buf++ = d0;
+		if (c2 != '=') *buf++ = d1;
+		if (c3 != '=') *buf++ = d2;
 	}
 
 	*decleno = buf - *deco;
@@ -219,13 +226,13 @@ main() {
 	char *r;
 	size_t l;
 	char test[] = "Keld_J=F8rn_Simonsen";
-	decode_qp(test, test + sizeof test, &r, &l);
+	blaze822_decode_qp(test, test + sizeof test, &r, &l);
 	printf("%s %d\n", r, l);
 
 	char *r2;
 	size_t l2;
-	char test2[] = "SWYgeW91IGNhbiByZWFkIHRoaXMgeW8=dSB1bmRlcnN0YW5kIHRoZSBleGFtcGxlLg==";
-	decode_b64(test2, test2+sizeof test2, &r2, &l2);
+	char test2[] = "SWYgeW91IGNhbiByZWFkIHRoaXMgeW8="; // dSB1bmRlcnN0YW5kIHRoZSBleGFtcGxlLg==";
+	blaze822_decode_b64(test2, test2+sizeof test2, &r2, &l2);
 	printf("%s %d\n", r2, l2);
 
 	char test3[] = "=?ISO-8859-1?Q?Keld_J=F8rn_Simonsen?= <keld@dkuug.dk>";