about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog3
-rw-r--r--resolv/inet_net_pton.c37
2 files changed, 24 insertions, 16 deletions
diff --git a/ChangeLog b/ChangeLog
index 7b3301eaeb..33f2662196 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,8 @@
 1999-10-02  Ulrich Drepper  <drepper@cygnus.com>
 
+	* resolv/inet_net_pton.c (inet_net_pton_ipv4): Prevent buffer
+	overruns.
+
 	* resolv/tst-aton.c (main): Add more tests.
 
 	* resolv/inet_addr.c (inet_aton): Correct some problems with to
diff --git a/resolv/inet_net_pton.c b/resolv/inet_net_pton.c
index 2f06c6803f..50ab9f8934 100644
--- a/resolv/inet_net_pton.c
+++ b/resolv/inet_net_pton.c
@@ -102,35 +102,41 @@ inet_net_pton_ipv4(src, dst, size)
 		if (size <= 0)
 			goto emsgsize;
 		*dst = 0, dirty = 0;
+		tmp = 0;	/* To calm down gcc.  */
 		src++;	/* skip x or X. */
-		while ((ch = *src++) != '\0' &&
-		       isascii(ch) && isxdigit(ch)) {
+		while (isxdigit((ch = *src++))) {
 			ch = _tolower(ch);
-			n = strchr(xdigits, ch) - xdigits;
+			n = (const char *) __rawmemchr(xdigits, ch) - xdigits;
 			assert(n >= 0 && n <= 15);
-			*dst |= n;
-			if (!dirty++)
-				*dst <<= 4;
-			else if (size-- > 0)
-				*++dst = 0, dirty = 0;
+			if (dirty == 0)
+				tmp = n << 4;
 			else
+				tmp |= n;
+			if (++dirty == 2) {
+				if (size-- <= 0)
+					goto emsgsize;
+				*dst++ = (u_char) tmp;
+				dirty = 0;
+			}
+		}
+		if (dirty) {
+			if (size-- <= 0)
 				goto emsgsize;
+			*dst = (u_char) tmp;
 		}
-		if (dirty)
-			size--;
 	} else if (isascii(ch) && isdigit(ch)) {
 		/* Decimal: eat dotted digit string. */
 		for (;;) {
 			tmp = 0;
 			do {
-				n = strchr(xdigits, ch) - xdigits;
+				n = ((const char *) __rawmemchr(xdigits, ch)
+				     - xdigits);
 				assert(n >= 0 && n <= 9);
 				tmp *= 10;
 				tmp += n;
 				if (tmp > 255)
 					goto enoent;
-			} while ((ch = *src++) != '\0' &&
-				 isascii(ch) && isdigit(ch));
+			} while (isascii((ch = *src++)) && isdigit(ch));
 			if (size-- <= 0)
 				goto emsgsize;
 			*dst++ = (u_char) tmp;
@@ -151,12 +157,11 @@ inet_net_pton_ipv4(src, dst, size)
 		ch = *src++;	/* Skip over the /. */
 		bits = 0;
 		do {
-			n = strchr(xdigits, ch) - xdigits;
+			n = (const char *) __rawmemchr(xdigits, ch) - xdigits;
 			assert(n >= 0 && n <= 9);
 			bits *= 10;
 			bits += n;
-		} while ((ch = *src++) != '\0' &&
-			 isascii(ch) && isdigit(ch));
+		} while (isascii((ch = *src++)) && isdigit(ch));
 		if (ch != '\0')
 			goto enoent;
 		if (bits > 32)