From a165074e8c41b143d967bc86cca0542b0119e13a Mon Sep 17 00:00:00 2001 From: Richard Walters Date: Wed, 4 Jul 2018 20:03:00 -0700 Subject: Fix bugs in IPv6 address parsing * Multiple colons should not be accepted in state 4. * After parsing a digit group and encountering a colon, we need allow either another colon or the beginning of either another group or an IPv4 address. Add state 5 to handle this. --- src/Uri.cpp | 29 +++++++++++++++++++++++++++-- test/src/UriTests.cpp | 2 ++ 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/Uri.cpp b/src/Uri.cpp index 30c9671..d9b2b46 100644 --- a/src/Uri.cpp +++ b/src/Uri.cpp @@ -317,7 +317,7 @@ namespace { if (c == ':') { numDigits = 0; ++numGroups; - state = 2; + state = 5; } else if (HEXDIG.Contains(c)) { if (++numDigits > 4) { return false; @@ -331,6 +331,7 @@ namespace { if (c == ':') { numDigits = 0; ++numGroups; + state = 2; } else if (c == '.') { ipv4AddressEncountered = true; break; @@ -347,6 +348,26 @@ namespace { return false; } } break; + + case 5: { // were in a group, encountered one colon + if (c == ':') { + if (doubleColonEncountered) { + return false; + } else { + doubleColonEncountered = true; + state = 2; + } + } else if (DIGIT.Contains(c)) { + potentialIpv4AddressStart = position; + ++numDigits; + state = 4; + } else if (HEXDIG.Contains(c)) { + ++numDigits; + state = 3; + } else { + return false; + } + } break; } if (ipv4AddressEncountered) { break; @@ -359,7 +380,11 @@ namespace { } if ( (position == address.length()) - && (state == 1) + && ( + (state == 1) + || (state == 2) + || (state == 5) + ) ) { // trailing single colon return false; } diff --git a/test/src/UriTests.cpp b/test/src/UriTests.cpp index efba4f1..027c045 100644 --- a/test/src/UriTests.cpp +++ b/test/src/UriTests.cpp @@ -722,8 +722,10 @@ TEST(UriTests, IPv6Address) { {"http://[::1]/", "::1", true}, {"http://[::ffff:1.2.3.4]/", "::ffff:1.2.3.4", true}, {"http://[2001:db8:85a3:8d3:1319:8a2e:370:7348]/", "2001:db8:85a3:8d3:1319:8a2e:370:7348", true}, + {"http://[fFfF::1]", "fFfF::1", true}, // invalid + {"http://[::fFfF::1]", "", false}, {"http://[::ffff:1.2.x.4]/", "", false}, {"http://[::ffff:1.2.3.4.8]/", "", false}, {"http://[::ffff:1.2.3]/", "", false}, -- cgit v1.2.3