[System]: Add missing System.Net.SecurityProtocolType enum values.
[mono.git] / mcs / class / System / System.Net / IPv6Address.cs
index 494ea66dca765b05b05fa29e39efd89df7df8b0d..d2103b24f79699e5e547a23fe75181cec7a8eb7a 100644 (file)
@@ -34,6 +34,7 @@
 \r
 \r
 using System;\r
+using System.Globalization;\r
 using System.Net.Sockets;\r
 using System.Runtime.InteropServices;\r
 using System.Text;\r
@@ -88,13 +89,14 @@ namespace System.Net {
                static int Fill (ushort [] addr, string ipString)\r
                {\r
                        int p = 0;\r
+                       int pdigits = 0;\r
                        int slot = 0;\r
 \r
                        if (ipString.Length == 0)\r
                                return 0;\r
                        \r
                        // Catch double uses of ::\r
-                       if (ipString.IndexOf ("::") != -1)\r
+                       if (ipString.IndexOf ("::", StringComparison.Ordinal) != -1)\r
                                return -1;\r
 \r
                        for (int i = 0; i < ipString.Length; i++){\r
@@ -102,6 +104,10 @@ namespace System.Net {
                                int n;\r
 \r
                                if (c == ':'){\r
+                                       // Leading : is not allowed.\r
+                                       if (i == 0)\r
+                                               return -1;\r
+                                      \r
                                        // Trailing : is not allowed.\r
                                        if (i == ipString.Length-1)\r
                                                return -1;\r
@@ -111,8 +117,13 @@ namespace System.Net {
                                        \r
                                        addr [slot++] = (ushort) p;\r
                                        p = 0;\r
+                                       pdigits = 0;\r
                                        continue;\r
-                               } if ('0' <= c && c <= '9')\r
+                               }\r
+                               pdigits++;\r
+                               if (pdigits > 4)\r
+                                       return -1;\r
+                               if ('0' <= c && c <= '9')\r
                                        n = (int) (c - '0');\r
                                else if ('a' <= c && c <= 'f')\r
                                        n = (int) (c - 'a' + 10);\r
@@ -132,6 +143,11 @@ namespace System.Net {
 \r
                        return slot;\r
                }\r
+\r
+               static bool TryParse (string prefix, out int res)\r
+               {\r
+                       return Int32.TryParse (prefix, NumberStyles.Integer, CultureInfo.InvariantCulture, out res);\r
+               }\r
                \r
                public static bool TryParse (string ipString, out IPv6Address result)\r
                {\r
@@ -152,11 +168,8 @@ namespace System.Net {
                        int pos = ipString.LastIndexOf ('/');\r
                        if (pos != -1) {\r
                                string prefix = ipString.Substring (pos + 1);\r
-                               try {\r
-                                       prefixLen = Int32.Parse (prefix);\r
-                               } catch (Exception) {\r
+                               if (!TryParse (prefix , out prefixLen))\r
                                        prefixLen = -1;\r
-                               }\r
                                if (prefixLen < 0 || prefixLen > 128)\r
                                        return false;\r
                                ipString = ipString.Substring (0, pos);\r
@@ -164,12 +177,8 @@ namespace System.Net {
                                pos = ipString.LastIndexOf ('%');\r
                                if (pos != -1) {\r
                                        string prefix = ipString.Substring (pos + 1);\r
-                                       try  {\r
-                                               scopeId = Int32.Parse (prefix);\r
-                                       } \r
-                                       catch (Exception) {\r
+                                       if (!TryParse (prefix, out scopeId))\r
                                                scopeId = 0;\r
-                                       }\r
                                        ipString = ipString.Substring (0, pos);\r
                                }                       \r
                        }\r
@@ -183,8 +192,7 @@ namespace System.Net {
                        //\r
                        // Is there an ipv4 address at the end?\r
                        //\r
-                       bool ipv4 = false;\r
-                       int pos2 = ipString.LastIndexOf (":");\r
+                       int pos2 = ipString.LastIndexOf (':');\r
                        if (pos2 == -1)\r
                                return false;\r
 \r
@@ -204,7 +212,6 @@ namespace System.Net {
                                                ipString = ipString.Substring (0, pos2 + 1);\r
                                        else\r
                                                ipString = ipString.Substring (0, pos2);\r
-                                       ipv4 = true;\r
                                        slots = 2;\r
                                }\r
                        }       \r
@@ -213,7 +220,7 @@ namespace System.Net {
                        // Only an ipv6 block remains, either:\r
                        // "hexnumbers::hexnumbers", "hexnumbers::" or "hexnumbers"\r
                        //\r
-                       int c = ipString.IndexOf ("::");\r
+                       int c = ipString.IndexOf ("::", StringComparison.Ordinal);\r
                        if (c != -1){\r
                                int right_slots = Fill (addr, ipString.Substring (c+2));\r
                                if (right_slots == -1){\r
@@ -241,24 +248,6 @@ namespace System.Net {
                                        return false;\r
                        }\r
 \r
-                       // Now check the results in the ipv6-address range only\r
-                       bool ipv6 = false;\r
-                       for (int i = 0; i < slots; i++){\r
-                               if (addr [i] != 0 || i == 5 && addr [i] != 0xffff)\r
-                                       ipv6 = true;\r
-                       }\r
-                       \r
-                       // check IPv4 validity\r
-                       if (ipv4 && !ipv6) {\r
-                               for (int i = 0; i < 5; i++) {\r
-                                       if (addr [i] != 0)\r
-                                               return false;\r
-                               }\r
-\r
-                               if (addr [5] != 0 && addr [5] != 0xffff)\r
-                                       return false;\r
-                       }\r
-\r
                        result = new IPv6Address (addr, prefixLen, scopeId);\r
                        return true;\r
                }\r
@@ -314,9 +303,10 @@ namespace System.Net {
                }\r
 \r
                // Convert the address into a format expected by the IPAddress (long) ctor\r
-               private int AsIPv4Int ()\r
+               // This needs to be unsigned to satisfy the '> 1' test in IsIPv4Compatible()\r
+               private uint AsIPv4Int ()\r
                {\r
-                       return (SwapUShort (address [7]) << 16) + SwapUShort (address [6]);\r
+                       return (uint)(SwapUShort (address [7]) << 16) + SwapUShort (address [6]);\r
                }                       \r
 \r
                public bool IsIPv4Compatible ()\r
@@ -324,6 +314,12 @@ namespace System.Net {
                        for (int i = 0; i < 6; i++) \r
                                if (address [i] != 0)\r
                                        return false;\r
+                       /* MS .net only seems to format the last 4\r
+                        * bytes as an IPv4 address if address[6] is\r
+                        * non-zero\r
+                        */\r
+                       if (address[6] == 0)\r
+                               return false;\r
                        return (AsIPv4Int () > 1);\r
                }\r
                \r
@@ -332,6 +328,13 @@ namespace System.Net {
                        for (int i = 0; i < 5; i++) \r
                                if (address [i] != 0)\r
                                        return false;\r
+                       /* MS .net only seems to format the last 4\r
+                        * bytes as an IPv4 address if address[6] is\r
+                        * non-zero\r
+                        */\r
+                       if (address[6] == 0)\r
+                               return false;\r
+                       \r
                        return address [5] == 0xffff;\r
                }\r
                \r