Update.
authorUlrich Drepper <drepper@redhat.com>
Sat, 2 Oct 1999 16:34:45 +0000 (16:34 +0000)
committerUlrich Drepper <drepper@redhat.com>
Sat, 2 Oct 1999 16:34:45 +0000 (16:34 +0000)
1999-10-02  Ulrich Drepper  <drepper@cygnus.com>

* resolv/tst-aton.c (main): Add more tests.

* resolv/inet_addr.c (inet_aton): Correct some problems with to
large numbers.  Optimize a bit.

ChangeLog
resolv/inet_addr.c
resolv/tst-aton.c

index 0962c90..7b3301e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+1999-10-02  Ulrich Drepper  <drepper@cygnus.com>
+
+       * resolv/tst-aton.c (main): Add more tests.
+
+       * resolv/inet_addr.c (inet_aton): Correct some problems with to
+       large numbers.  Optimize a bit.
+
 1999-10-01  Ulrich Drepper  <drepper@cygnus.com>
 
        * resolv/inet_net_ntop.c (inet_net_ntop_ipv4): If BITS is zero
index d9b3701..e7f56d4 100644 (file)
@@ -60,6 +60,8 @@ static char rcsid[] = "$Id$";
 #include <arpa/inet.h>
 #include <ctype.h>
 #ifdef _LIBC
+# include <endian.h>
+# include <stdint.h>
 # include <stdlib.h>
 # include <limits.h>
 # include <errno.h>
@@ -100,17 +102,24 @@ inet_aton(cp, addr)
 #ifndef _LIBC
        register int base;
 #endif
-       register int n;
        register char c;
-       u_int32_t parts[4];
-       register u_int32_t *pp = parts;
+       union iaddr {
+         uint8_t bytes[4];
+         uint32_t word;
+       } res;
+#if BYTE_ORDER == LITTLE_ENDIAN
+       register uint8_t *pp = res.bytes;
+#else
+       register uint8_t *pp = &res.bytes[4];
+#endif
+       int digit;
 
 #ifdef _LIBC
        int saved_errno = errno;
        __set_errno (0);
 #endif
 
-       memset (parts, '\0', sizeof (parts));
+       res.word = 0;
 
        c = *cp;
        for (;;) {
@@ -123,12 +132,15 @@ inet_aton(cp, addr)
                        goto ret_0;
 #ifdef _LIBC
                {
-                       unsigned long ul = strtoul (cp, (char **) &cp, 0);
+                       char *endp;
+                       unsigned long ul = strtoul (cp, (char **) &endp, 0);
                        if (ul == ULONG_MAX && errno == ERANGE)
                                goto ret_0;
                        if (ul > 0xfffffffful)
                                goto ret_0;
                        val = ul;
+                       digit = cp != endp;
+                       cp = endp;
                }
                c = *cp;
 #else
@@ -160,9 +172,17 @@ inet_aton(cp, addr)
                         *      a.b.c   (with c treated as 16 bits)
                         *      a.b     (with b treated as 24 bits)
                         */
-                       if (pp >= parts + 3)
+                       if ((BYTE_ORDER == LITTLE_ENDIAN
+                            && pp >= res.bytes + 3)
+                           || (BYTE_ORDER == BIG_ENDIAN
+                               && pp == res.bytes)
+                           || val > 0xff)
                                goto ret_0;
+#if BYTE_ORDER == LITTLE_ENDIAN
                        *pp++ = val;
+#else
+                       *--pp = val;
+#endif
                        c = *++cp;
                } else
                        break;
@@ -172,21 +192,21 @@ inet_aton(cp, addr)
         */
        if (c != '\0' && (!isascii(c) || !isspace(c)))
                goto ret_0;
+
        /*
-        * Concoct the address according to
-        * the number of parts specified.
+        * Did we get a valid digit?
         */
-       n = pp - parts + 1;
+       if (!digit)
+               goto ret_0;
 
-       if (n == 0      /* initial nondigit */
-           || parts[0] > 0xff || parts[1] > 0xff || parts[2] > 0xff
-           || val > max[n - 1])
+       /* Check whether the last part is in its limits depending on
+          the number of parts in total.  */
+       if ((BYTE_ORDER == LITTLE_ENDIAN && val > max[pp - res.bytes])
+           || (BYTE_ORDER == BIG_ENDIAN && val > max[res.bytes - pp]))
          goto ret_0;
 
-       val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
-
        if (addr)
-               addr->s_addr = htonl(val);
+               addr->s_addr = res.word | htonl (val);
 
 #ifdef _LIBC
        __set_errno (saved_errno);
index 818f9ed..79077b0 100644 (file)
@@ -3,19 +3,69 @@
 #include <netinet/in.h>
 #include <arpa/inet.h>
 
-enum { buf_size = 16 };
-static char buf[buf_size] = "323543357756889";
+
+static struct tests
+{
+  const char *input;
+  int valid;
+  uint32_t result;
+} tests[] =
+{
+  { "", 0, 0 },
+  { "-1", 0, 0 },
+  { "256", 1, 0x00000100 },
+  { "256.", 0, 0 },
+  { "256a", 0, 0 },
+  { "0x100", 1, 0x00000100 },
+  { "0200.0x123456", 1, 0x80123456 },
+  { "0300.0x89123456.", 0 ,0 },
+  { "0100.-0xffff0000", 0, 0 },
+  { "0.0xffffff", 1, 0x00ffffff },
+  { "0.0x1000000", 0, 0 },
+  { "0377.16777215", 1, 0xffffffff },
+  { "0377.16777216", 0, 0 },
+  { "0x87.077777777", 1, 0x87ffffff },
+  { "0x87.0100000000", 0, 0 },
+  { "0.1.3", 1, 0x00010003 },
+  { "0.256.3", 0, 0 },
+  { "256.1.3", 0, 0 },
+  { "0.1.0x10000", 0, 0 },
+  { "0.1.0xffff", 1, 0x0001ffff },
+  { "0.1a.3", 0, 0 },
+  { "0.1.a3", 0, 0 },
+  { "1.2.3.4", 1, 0x01020304 },
+  { "0400.2.3.4", 0, 0 },
+  { "1.0x100.3.4", 0, 0 },
+  { "1.2.256.4", 0, 0 },
+  { "1.2.3.0x100", 0, 0 },
+  { "323543357756889", 0, 0 },
+};
+
 
 int
 main (int argc, char *argv[])
 {
-  struct in_addr addr;
   int result = 0;
+  int cnt;
 
-  if (inet_aton (buf, &addr) != 0)
+  for (cnt = 0; cnt < sizeof (tests) / sizeof (tests[0]); ++cnt)
     {
-      printf ("%s is seen as a valid IP address\n", buf);
-      result = 1;
+      struct in_addr addr;
+
+      if (inet_aton (tests[cnt].input, &addr) != tests[cnt].valid)
+       {
+         if (tests[cnt].valid)
+           printf ("\"%s\" not seen as valid IP address\n", tests[cnt].input);
+         else
+           printf ("\"%s\" seen as valid IP address\n", tests[cnt].input);
+         result = 1;
+       }
+      else if (tests[cnt].valid && addr.s_addr != ntohl (tests[cnt].result))
+       {
+         printf ("\"%s\" not converted correctly: is %08x, should be %08x\n",
+                 tests[cnt].input, addr.s_addr, tests[cnt].result);
+         result = 1;
+       }
     }
 
   return result;