aboutsummaryrefslogtreecommitdiff
path: root/resolv/inet_net_pton.c
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>1999-10-02 20:41:15 +0000
committerUlrich Drepper <drepper@redhat.com>1999-10-02 20:41:15 +0000
commit0c03cb9bedf3454129ac8e50ab2d3db9b7260c78 (patch)
treed2e8e8ed7102ed7ec07816b608e023a375828f19 /resolv/inet_net_pton.c
parent81ca53df7dea9967eeb56d47376e0f3fd2c9edda (diff)
downloadglibc-0c03cb9bedf3454129ac8e50ab2d3db9b7260c78.zip
glibc-0c03cb9bedf3454129ac8e50ab2d3db9b7260c78.tar.gz
glibc-0c03cb9bedf3454129ac8e50ab2d3db9b7260c78.tar.bz2
Update.
* resolv/inet_net_pton.c (inet_net_pton_ipv4): Prevent buffer overruns.
Diffstat (limited to 'resolv/inet_net_pton.c')
-rw-r--r--resolv/inet_net_pton.c37
1 files changed, 21 insertions, 16 deletions
diff --git a/resolv/inet_net_pton.c b/resolv/inet_net_pton.c
index 2f06c68..50ab9f8 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)