diff options
author | Scallop Ye <yescallop@gmail.com> | 2022-10-04 21:11:08 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-10-04 15:11:08 +0200 |
commit | eff4facd6d165d7206ff6cae1706591c2dadf4a7 (patch) | |
tree | c54a4cbb612d675d6a9e41499a89b328d21bcb64 | |
parent | a0b9b251787f1053cae90c793c8433af4028c2d1 (diff) | |
download | uriparser-eff4facd6d165d7206ff6cae1706591c2dadf4a7.tar.gz |
Fix IPv6 and IPvFuture literal parsing (#150)
-rw-r--r-- | src/UriParse.c | 29 | ||||
-rw-r--r-- | test/test.cpp | 38 |
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) { |