aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Walters <rwalters@digitalstirling.com>2018-07-04 20:03:00 -0700
committerRichard Walters <rwalters@digitalstirling.com>2018-07-04 20:03:00 -0700
commita165074e8c41b143d967bc86cca0542b0119e13a (patch)
treef9e3df0ad13a30e0f012f9a703a2027a9f6cd8a2
parent7d5f93777026f46870f14d85c22872bb42bd40d5 (diff)
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.
-rw-r--r--src/Uri.cpp29
-rw-r--r--test/src/UriTests.cpp2
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},