summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorScallop Ye <yescallop@gmail.com>2022-10-04 21:11:08 +0800
committerGitHub <noreply@github.com>2022-10-04 15:11:08 +0200
commiteff4facd6d165d7206ff6cae1706591c2dadf4a7 (patch)
treec54a4cbb612d675d6a9e41499a89b328d21bcb64
parenta0b9b251787f1053cae90c793c8433af4028c2d1 (diff)
downloaduriparser-eff4facd6d165d7206ff6cae1706591c2dadf4a7.tar.gz
Fix IPv6 and IPvFuture literal parsing (#150)
-rw-r--r--src/UriParse.c29
-rw-r--r--test/test.cpp38
2 files changed, 51 insertions, 16 deletions
diff --git a/src/UriParse.c b/src/UriParse.c
index eefa8d1..a672c8e 100644
--- a/src/UriParse.c
+++ b/src/UriParse.c
@@ -478,6 +478,7 @@ static const URI_CHAR * URI_FUNC(ParseIpFuture)(URI_TYPE(ParserState) * state,
switch (*first) {
case _UT('v'):
+ case _UT('V'):
*/
if (first + 1 >= afterLast) {
URI_FUNC(StopSyntax)(state, afterLast, memory);
@@ -540,7 +541,9 @@ static URI_INLINE const URI_CHAR * URI_FUNC(ParseIpLit2)(
}
switch (*first) {
+ /* The leading "v" of IPvFuture is case-insensitive. */
case _UT('v'):
+ case _UT('V'):
{
const URI_CHAR * const afterIpFuture
= URI_FUNC(ParseIpFuture)(state, first, afterLast, memory);
@@ -624,11 +627,6 @@ static const URI_CHAR * URI_FUNC(ParseIPv6address2)(
/* Leading zero */
URI_FUNC(StopSyntax)(state, first - digitCount, memory);
return NULL;
- } else if ((digitCount > 2)
- && (digitHistory[1] == 0)) {
- /* Leading zero */
- URI_FUNC(StopSyntax)(state, first - digitCount + 1, memory);
- return NULL;
} else if ((digitCount == 3)
&& (100 * digitHistory[0]
+ 10 * digitHistory[1]
@@ -662,11 +660,6 @@ static const URI_CHAR * URI_FUNC(ParseIPv6address2)(
/* Leading zero */
URI_FUNC(StopSyntax)(state, first - digitCount, memory);
return NULL;
- } else if ((digitCount > 2)
- && (digitHistory[1] == 0)) {
- /* Leading zero */
- URI_FUNC(StopSyntax)(state, first - digitCount + 1, memory);
- return NULL;
} else if ((digitCount == 3)
&& (100 * digitHistory[0]
+ 10 * digitHistory[1]
@@ -788,6 +781,10 @@ static const URI_CHAR * URI_FUNC(ParseIPv6address2)(
URI_FUNC(StopSyntax)(state, first + 1, memory);
return NULL; /* ":::+ "*/
}
+ } else if (quadsDone == 0 || first[1] == _UT(']')) {
+ /* Single leading or trailing ":" */
+ URI_FUNC(StopSyntax)(state, first, memory);
+ return NULL;
}
if (setZipper) {
@@ -797,7 +794,7 @@ static const URI_CHAR * URI_FUNC(ParseIPv6address2)(
break;
case _UT('.'):
- if ((quadsDone > 6) /* NOTE */
+ if ((quadsDone + zipperEver > 6) /* NOTE */
|| (!zipperEver && (quadsDone < 6))
|| letterAmong
|| (digitCount == 0)
@@ -810,11 +807,6 @@ static const URI_CHAR * URI_FUNC(ParseIPv6address2)(
/* Leading zero */
URI_FUNC(StopSyntax)(state, first - digitCount, memory);
return NULL;
- } else if ((digitCount > 2)
- && (digitHistory[1] == 0)) {
- /* Leading zero */
- URI_FUNC(StopSyntax)(state, first - digitCount + 1, memory);
- return NULL;
} else if ((digitCount == 3)
&& (100 * digitHistory[0]
+ 10 * digitHistory[1]
@@ -848,6 +840,11 @@ static const URI_CHAR * URI_FUNC(ParseIPv6address2)(
if (digitCount > 0) {
if (zipperEver) {
+ /* Too many quads? */
+ if (quadsDone >= 7) {
+ URI_FUNC(StopSyntax)(state, first, memory);
+ return NULL;
+ }
uriWriteQuadToDoubleByte(digitHistory, digitCount, quadsAfterZipper + 2 * quadsAfterZipperCount);
quadsAfterZipperCount++;
} else {
diff --git a/test/test.cpp b/test/test.cpp
index 31e9866..fade025 100644
--- a/test/test.cpp
+++ b/test/test.cpp
@@ -213,6 +213,18 @@ TEST(UriSuite, TestIpSixPass) {
URI_TEST_IP_SIX_PASS("2001:db8:100:f101::1");
URI_TEST_IP_SIX_PASS("a:b:c::12:1");
URI_TEST_IP_SIX_PASS("a:b::0:1:2:3");
+
+ // Issue #146: These are not leading zeros.
+ URI_TEST_IP_SIX_PASS("::100.1.1.1");
+ URI_TEST_IP_SIX_PASS("::1.100.1.1");
+ URI_TEST_IP_SIX_PASS("::1.1.100.1");
+ URI_TEST_IP_SIX_PASS("::1.1.1.100");
+ URI_TEST_IP_SIX_PASS("::100.100.100.100");
+ URI_TEST_IP_SIX_PASS("::10.1.1.1");
+ URI_TEST_IP_SIX_PASS("::1.10.1.1");
+ URI_TEST_IP_SIX_PASS("::1.1.10.1");
+ URI_TEST_IP_SIX_PASS("::1.1.1.10");
+ URI_TEST_IP_SIX_PASS("::10.10.10.10");
}
TEST(UriSuite, TestIpSixFail) {
@@ -259,6 +271,32 @@ TEST(UriSuite, TestIpSixFail) {
// Nonhex
URI_TEST_IP_SIX_FAIL("g:0:0:0:0:0:0");
+
+ // Issue #146: Zipper between the 7th and 8th quads.
+ URI_TEST_IP_SIX_FAIL("0:0:0:0:0:0:0::1");
+
+ // Issue #146: Leading or trailing ":".
+ URI_TEST_IP_SIX_FAIL(":1::1");
+ URI_TEST_IP_SIX_FAIL("1::1:");
+ URI_TEST_IP_SIX_FAIL(":1::1:");
+ URI_TEST_IP_SIX_FAIL(":0:0:0:0:0:0:0:0");
+ URI_TEST_IP_SIX_FAIL("0:0:0:0:0:0:0:0:");
+ URI_TEST_IP_SIX_FAIL(":0:0:0:0:0:0:0:0:");
+
+ // Issue #146: Zipper between six quads and IPv4 address.
+ URI_TEST_IP_SIX_FAIL("1:1:1:1:1:1::1.1.1.1");
+}
+
+TEST(UriSuite, TestIpFuture) {
+ UriParserStateA stateA;
+ UriUriA uriA;
+ stateA.uri = &uriA;
+
+ // Issue #146: The leading "v" of IPvFuture is case-insensitive.
+ ASSERT_TRUE(0 == uriParseUriA(&stateA, "//[vF.addr]"));
+ uriFreeUriMembersA(&uriA);
+ ASSERT_TRUE(0 == uriParseUriA(&stateA, "//[VF.addr]"));
+ uriFreeUriMembersA(&uriA);
}
TEST(UriSuite, TestIpSixOverread) {