Module Name:    src
Committed By:   martin
Date:           Tue Nov 25 15:23:36 UTC 2014

Modified Files:
        src/lib/libc/net [netbsd-7]: base64.c

Log Message:
Pull up following revision(s) (requested by christos in ticket #264):
        lib/libc/net/base64.c: revision 1.15
        lib/libc/net/base64.c: revision 1.16
Don't read past the end when the data is exactly the right size. Reported
by tedu @ openbsd in tech-userlevel. Thanks!
knf, no functional change.


To generate a diff of this commit:
cvs rdiff -u -r1.14 -r1.14.10.1 src/lib/libc/net/base64.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/lib/libc/net/base64.c
diff -u src/lib/libc/net/base64.c:1.14 src/lib/libc/net/base64.c:1.14.10.1
--- src/lib/libc/net/base64.c:1.14	Mon Jun 25 22:32:44 2012
+++ src/lib/libc/net/base64.c	Tue Nov 25 15:23:36 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: base64.c,v 1.14 2012/06/25 22:32:44 abs Exp $	*/
+/*	$NetBSD: base64.c,v 1.14.10.1 2014/11/25 15:23:36 martin Exp $	*/
 
 /*
  * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
@@ -47,7 +47,7 @@
 #if 0
 static const char rcsid[] = "Id: base64.c,v 1.4 2005/04/27 04:56:34 sra Exp";
 #else
-__RCSID("$NetBSD: base64.c,v 1.14 2012/06/25 22:32:44 abs Exp $");
+__RCSID("$NetBSD: base64.c,v 1.14.10.1 2014/11/25 15:23:36 martin Exp $");
 #endif
 #endif /* LIBC_SCCS and not lint */
 
@@ -155,11 +155,11 @@ b64_ntop(u_char const *src, size_t srcle
 		input[2] = *src++;
 		srclength -= 3;
 
-		output[0] = (u_int32_t)input[0] >> 2;
-		output[1] = ((u_int32_t)(input[0] & 0x03) << 4) +
-		    ((u_int32_t)input[1] >> 4);
-		output[2] = ((u_int32_t)(input[1] & 0x0f) << 2) +
-		    ((u_int32_t)input[2] >> 6);
+		output[0] = (uint32_t)input[0] >> 2;
+		output[1] = ((uint32_t)(input[0] & 0x03) << 4) +
+		    ((uint32_t)input[1] >> 4);
+		output[2] = ((uint32_t)(input[1] & 0x0f) << 2) +
+		    ((uint32_t)input[2] >> 6);
 		output[3] = input[2] & 0x3f;
 		Assert(output[0] < 64);
 		Assert(output[1] < 64);
@@ -167,7 +167,7 @@ b64_ntop(u_char const *src, size_t srcle
 		Assert(output[3] < 64);
 
 		if (datalength + 4 > targsize)
-			return (-1);
+			return -1;
 		target[datalength++] = Base64[output[0]];
 		target[datalength++] = Base64[output[1]];
 		target[datalength++] = Base64[output[2]];
@@ -181,17 +181,17 @@ b64_ntop(u_char const *src, size_t srcle
 		for (i = 0; i < srclength; i++)
 			input[i] = *src++;
 	
-		output[0] = (u_int32_t)input[0] >> 2;
-		output[1] = ((u_int32_t)(input[0] & 0x03) << 4) +
-		    ((u_int32_t)input[1] >> 4);
-		output[2] = ((u_int32_t)(input[1] & 0x0f) << 2) +
-		    ((u_int32_t)input[2] >> 6);
+		output[0] = (uint32_t)input[0] >> 2;
+		output[1] = ((uint32_t)(input[0] & 0x03) << 4) +
+		    ((uint32_t)input[1] >> 4);
+		output[2] = ((uint32_t)(input[1] & 0x0f) << 2) +
+		    ((uint32_t)input[2] >> 6);
 		Assert(output[0] < 64);
 		Assert(output[1] < 64);
 		Assert(output[2] < 64);
 
 		if (datalength + 4 > targsize)
-			return (-1);
+			return -1;
 		target[datalength++] = Base64[output[0]];
 		target[datalength++] = Base64[output[1]];
 		if (srclength == 1U)
@@ -201,7 +201,7 @@ b64_ntop(u_char const *src, size_t srcle
 		target[datalength++] = Pad64;
 	}
 	if (datalength >= targsize)
-		return (-1);
+		return -1;
 	target[datalength] = '\0';	/*%< Returned value doesn't count \\0. */
 	_DIAGASSERT(__type_fit(int, datalength));
 	return (int)datalength;
@@ -218,6 +218,7 @@ b64_pton(char const *src, u_char *target
 {
 	size_t tarindex;
 	int state, ch;
+	u_char nextbyte;
 	char *pos;
 
 	_DIAGASSERT(src != NULL);
@@ -234,41 +235,44 @@ b64_pton(char const *src, u_char *target
 			break;
 
 		pos = strchr(Base64, ch);
-		if (pos == 0) 		/*%< A non-base64 character. */
-			return (-1);
+		if (pos == NULL) 	/*%< A non-base64 character. */
+			return -1;
 
 		switch (state) {
 		case 0:
 			if (target) {
-				if ((size_t)tarindex >= targsize)
-					return (-1);
-				target[tarindex] =
-				    (unsigned char)(pos - Base64) << 2;
+				if (tarindex >= targsize)
+					return -1;
+				target[tarindex] = (u_char)(pos - Base64) << 2;
 			}
 			state = 1;
 			break;
 		case 1:
 			if (target) {
-				if ((size_t)tarindex + 1 >= targsize)
-					return (-1);
+				if (tarindex >= targsize)
+					return -1;
 				target[tarindex] |= 
-				    (u_int32_t)(pos - Base64) >> 4;
-				target[tarindex+1]  = 
-				    (unsigned char)
-				    (((pos - Base64) & 0x0f) << 4);
+				    (uint32_t)(pos - Base64) >> 4;
+				nextbyte = (u_char)((pos - Base64) & 0x0f) << 4;
+				if (tarindex + 1 < targsize)
+					target[tarindex + 1] = nextbyte;
+				else if (nextbyte)
+					return -1;
 			}
 			tarindex++;
 			state = 2;
 			break;
 		case 2:
 			if (target) {
-				if ((size_t)tarindex + 1 >= targsize)
-					return (-1);
+				if (tarindex >= targsize)
+					return -1;
 				target[tarindex] |= 
-					(u_int32_t)(pos - Base64) >> 2;
-				target[tarindex+1] =
-				    (unsigned char)
-				    (((pos - Base64) & 0x03) << 6);
+					(uint32_t)(pos - Base64) >> 2;
+				nextbyte = (u_char)((pos - Base64) & 0x03) << 6;
+				if (tarindex + 1 < targsize)
+					target[tarindex + 1] = nextbyte;
+				else if (nextbyte)
+					return -1;
 			}
 			tarindex++;
 			state = 3;
@@ -276,9 +280,8 @@ b64_pton(char const *src, u_char *target
 		case 3:
 			if (target) {
 				if ((size_t)tarindex >= targsize)
-					return (-1);
-				target[tarindex] |=
-				    (unsigned char)(pos - Base64);
+					return -1;
+				target[tarindex] |= (u_char)(pos - Base64);
 			}
 			tarindex++;
 			state = 0;
@@ -298,7 +301,7 @@ b64_pton(char const *src, u_char *target
 		switch (state) {
 		case 0:		/*%< Invalid = in first position */
 		case 1:		/*%< Invalid = in second position */
-			return (-1);
+			return -1;
 
 		case 2:		/*%< Valid, means one byte of info */
 			/* Skip any number of spaces. */
@@ -307,7 +310,7 @@ b64_pton(char const *src, u_char *target
 					break;
 			/* Make sure there is another trailing = sign. */
 			if (ch != Pad64)
-				return (-1);
+				return -1;
 			ch = *src++;		/*%< Skip the = */
 			/* Fall through to "single trailing =" case. */
 			/* FALLTHROUGH */
@@ -319,7 +322,7 @@ b64_pton(char const *src, u_char *target
 			 */
 			for (; ch != '\0'; ch = (u_char) *src++)
 				if (!isspace(ch))
-					return (-1);
+					return -1;
 
 			/*
 			 * Now make sure for cases 2 and 3 that the "extra"
@@ -327,8 +330,9 @@ b64_pton(char const *src, u_char *target
 			 * zeros.  If we don't check them, they become a
 			 * subliminal channel.
 			 */
-			if (target && target[tarindex] != 0)
-				return (-1);
+			if (target && tarindex < targsize &&
+			    target[tarindex] != 0)
+				return -1;
 		}
 	} else {
 		/*
@@ -336,7 +340,7 @@ b64_pton(char const *src, u_char *target
 		 * have no partial bytes lying around.
 		 */
 		if (state != 0)
-			return (-1);
+			return -1;
 	}
 
 	_DIAGASSERT(__type_fit(int, tarindex));

Reply via email to