diff --git a/shared/src/main/scala/com/comcast/ip4s/Host.scala b/shared/src/main/scala/com/comcast/ip4s/Host.scala index 88cd7b1..218ac80 100644 --- a/shared/src/main/scala/com/comcast/ip4s/Host.scala +++ b/shared/src/main/scala/com/comcast/ip4s/Host.scala @@ -773,6 +773,7 @@ object Ipv6Address extends Ipv6AddressCompanionPlatform { } idx += 1 } + if (result ne null) { result } else if (fields.isEmpty && (trimmed.isEmpty || trimmed != "::")) { @@ -781,26 +782,34 @@ object Ipv6Address extends Ipv6AddressCompanionPlatform { val bytes = new Array[Byte](16) idx = 0 val prefixSize = prefix.size - var prefixIdx = prefixSize - 1 - while (prefixIdx >= 0) { - val value = prefix(prefixIdx) - bytes(idx) = (value >> 8).toByte - bytes(idx + 1) = value.toByte - prefixIdx -= 1 - idx += 2 - } val suffixSize = suffix.size - val numCondensedZeroes = bytes.size - idx - (suffixSize * 2) - idx += numCondensedZeroes - var suffixIdx = suffixSize - 1 - while (suffixIdx >= 0) { - val value = suffix(suffixIdx) - bytes(idx) = (value >> 8).toByte - bytes(idx + 1) = value.toByte - suffixIdx -= 1 - idx += 2 + val numCondensedZeroes = 8 - (prefixSize + suffixSize) + + if (numCondensedZeroes < 0) { + None + } else { + var prefixIdx = prefixSize - 1 + while (prefixIdx >= 0) { + val value = prefix(prefixIdx) + bytes(idx) = (value >> 8).toByte + bytes(idx + 1) = value.toByte + prefixIdx -= 1 + idx += 2 + } + + idx += numCondensedZeroes * 2 + + var suffixIdx = suffixSize - 1 + while (suffixIdx >= 0) { + val value = suffix(suffixIdx) + bytes(idx) = (value >> 8).toByte + bytes(idx + 1) = value.toByte + suffixIdx -= 1 + idx += 2 + } + + Some(unsafeFromBytes(bytes)) } - Some(unsafeFromBytes(bytes)) } } diff --git a/test-kit/shared/src/test/scala/com/comcast/ip4s/Ipv6AddressTest.scala b/test-kit/shared/src/test/scala/com/comcast/ip4s/Ipv6AddressTest.scala index 476786a..695fca2 100644 --- a/test-kit/shared/src/test/scala/com/comcast/ip4s/Ipv6AddressTest.scala +++ b/test-kit/shared/src/test/scala/com/comcast/ip4s/Ipv6AddressTest.scala @@ -35,6 +35,11 @@ class Ipv6AddressTest extends BaseTestSuite { assertEquals(Ipv6Address.fromString(" : "), None) } + test("parsing from string - does not parse invalid number of sections in ipv6") { + assertEquals(Ipv6Address.fromString("::1:1:1:1:1:1:2:1:3"), None) + assertEquals(Ipv6Address.fromString("1:1:1:1:1:1:2:1:3"), None) + } + test("parsing from string - does parse ::") { assertEquals(Ipv6Address.fromString("::").isDefined, true) assertEquals(Ipv6Address.fromString(" :: ").isDefined, true) @@ -150,4 +155,5 @@ class Ipv6AddressTest extends BaseTestSuite { assert(ipv6"fe80::1".isLinkLocal) assert(ipv6"::ffff:169.254.0.0".isLinkLocal) } + }