From 8d16abd980122b4d4b24aad345efb95373c11c18 Mon Sep 17 00:00:00 2001 From: Steve Hanson Date: Wed, 30 Jun 2021 17:09:52 +0100 Subject: [PATCH] Uri Parse improvements --- include/rapidjson/uri.h | 33 +++++++++++++-------------------- test/unittest/uritest.cpp | 15 +++++++++++++++ 2 files changed, 28 insertions(+), 20 deletions(-) diff --git a/include/rapidjson/uri.h b/include/rapidjson/uri.h index 6353c32..7de7b80 100644 --- a/include/rapidjson/uri.h +++ b/include/rapidjson/uri.h @@ -295,24 +295,17 @@ private: // Look for auth (//([^/?#]*))? auth_ = scheme_ + GetSchemeStringLength() + 1; *auth_ = '\0'; - if (start < len) { - pos1 = start; - while (pos1 < len) { - if (uri[pos1] == '/' && uri[pos1 + 1] == '/') break; - pos1++; - } - if (pos1 == start) { - pos2 = start + 2; - while (pos2 < len) { - if (uri[pos2] == '/') break; - if (uri[pos2] == '?') break; - if (uri[pos2] == '#') break; - pos2++; - } - std::memcpy(auth_, &uri[start], (pos2 - start) * sizeof(Ch)); - auth_[pos2 - start] = '\0'; - start = pos2; + if (start < len - 1 && uri[start] == '/' && uri[start + 1] == '/') { + pos2 = start + 2; + while (pos2 < len) { + if (uri[pos2] == '/') break; + if (uri[pos2] == '?') break; + if (uri[pos2] == '#') break; + pos2++; } + std::memcpy(auth_, &uri[start], (pos2 - start) * sizeof(Ch)); + auth_[pos2 - start] = '\0'; + start = pos2; } // Look for path ([^?#]*) path_ = auth_ + GetAuthStringLength() + 1; @@ -335,8 +328,8 @@ private: // Look for query (\?([^#]*))? query_ = path_ + GetPathStringLength() + 1; *query_ = '\0'; - if (start < len) { - pos2 = start; + if (start < len && uri[start] == '?') { + pos2 = start + 1; while (pos2 < len) { if (uri[pos2] == '#') break; pos2++; @@ -350,7 +343,7 @@ private: // Look for fragment (#(.*))? frag_ = query_ + GetQueryStringLength() + 1; *frag_ = '\0'; - if (start < len) { + if (start < len && uri[start] == '#') { std::memcpy(frag_, &uri[start], (len - start) * sizeof(Ch)); frag_[len - start] = '\0'; } diff --git a/test/unittest/uritest.cpp b/test/unittest/uritest.cpp index 6cfa27d..5506aa1 100644 --- a/test/unittest/uritest.cpp +++ b/test/unittest/uritest.cpp @@ -160,6 +160,14 @@ TEST(Uri, Parse) { EXPECT_TRUE(u.GetBaseStringLength() == 0); EXPECT_TRUE(StrCmp(u.GetFragString(), "#frag/stuff") == 0); EXPECT_TRUE(u.GetFragStringLength() == len); + + // Incomplete auth treated as path + str = "http:/"; + const UriType u2 = UriType(str); + EXPECT_TRUE(StrCmp(u2.GetSchemeString(), "http:") == 0); + EXPECT_TRUE(u2.GetAuthStringLength() == 0); + EXPECT_TRUE(StrCmp(u2.GetPathString(), "/") == 0); + EXPECT_TRUE(StrCmp(u2.GetBaseString(), "http:/") == 0); } TEST(Uri, Parse_UTF16) { @@ -274,6 +282,13 @@ TEST(Uri, Parse_UTF16) { EXPECT_TRUE(u.GetBaseStringLength() == 0); EXPECT_TRUE(StrCmp(u.GetFragString(), L"#frag/stuff") == 0); EXPECT_TRUE(u.GetFragStringLength() == len); + + // Incomplete auth treated as path + u = UriType(L"http:/"); + EXPECT_TRUE(StrCmp(u.GetSchemeString(), L"http:") == 0); + EXPECT_TRUE(u.GetAuthStringLength() == 0); + EXPECT_TRUE(StrCmp(u.GetPathString(), L"/") == 0); + EXPECT_TRUE(StrCmp(u.GetBaseString(), L"http:/") == 0); } TEST(Uri, CopyConstructor) {