Fixing invalid IPv6 address parsing stack underflow on Windows.

Occurred when parsing an address with more than 7 colons. For example:
1::2:3:4:5:6:7::8

BUG=webrtc:7592

Review-Url: https://codereview.webrtc.org/2867653002
Cr-Commit-Position: refs/heads/master@{#18054}
diff --git a/webrtc/base/win32.cc b/webrtc/base/win32.cc
index 485f7a6..89970ec 100644
--- a/webrtc/base/win32.cc
+++ b/webrtc/base/win32.cc
@@ -276,6 +276,11 @@
             ++coloncounter;
           }
           // (coloncount + 1) is the number of shorts left in the address.
+          // If this number is greater than the number of available shorts, the
+          // address is malformed.
+          if (coloncount + 1 > addr_end - addr_cursor) {
+            return 0;
+          }
           addr_cursor = addr_end - (coloncount + 1);
           seencompressed = true;
         }
@@ -285,7 +290,7 @@
     } else {
       uint16_t word;
       int bytesread = 0;
-      if (sscanf(readcursor, "%hx%n", &word, &bytesread) != 1) {
+      if (sscanf(readcursor, "%4hx%n", &word, &bytesread) != 1) {
         return 0;
       } else {
         *addr_cursor = HostToNetwork16(word);
diff --git a/webrtc/base/win32_unittest.cc b/webrtc/base/win32_unittest.cc
index 15b2614..96e0bd2 100644
--- a/webrtc/base/win32_unittest.cc
+++ b/webrtc/base/win32_unittest.cc
@@ -92,4 +92,31 @@
   EXPECT_EQ("1234:5678:abcd:1234:5678:abcd:1234:5678", ipv6.ToString());
 }
 
+// Test that invalid IPv6 addresses are recognized and false is returned.
+TEST_F(Win32Test, InvalidIPv6AddressParsing) {
+  IPAddress ipv6;
+
+  // More than 1 run of "::"s.
+  EXPECT_FALSE(IPFromString("1::2::3", &ipv6));
+
+  // More than 1 run of "::"s in a longer address.
+  // See: https://bugs.chromium.org/p/webrtc/issues/detail?id=7592
+  EXPECT_FALSE(IPFromString("1::2::3::4::5::6::7::8", &ipv6));
+
+  // Three ':'s in a row.
+  EXPECT_FALSE(IPFromString("1:::2", &ipv6));
+
+  // Non-hex character.
+  EXPECT_FALSE(IPFromString("test::1", &ipv6));
+
+  // More than 4 hex digits per group.
+  EXPECT_FALSE(IPFromString("abcde::1", &ipv6));
+
+  // More than 8 groups.
+  EXPECT_FALSE(IPFromString("1:2:3:4:5:6:7:8:9", &ipv6));
+
+  // Less than 8 groups.
+  EXPECT_FALSE(IPFromString("1:2:3:4:5:6:7", &ipv6));
+}
+
 }  // namespace rtc