From fa1e74553f4cbc1567008744857291fbc5629d11 Mon Sep 17 00:00:00 2001 From: Minh Vu Date: Fri, 12 Jun 2026 20:44:29 +0200 Subject: [PATCH] Fix URI fragment parsing without query Signed-off-by: Minh Vu --- dali/util/uri.cc | 30 ++++++++++++++++-------------- dali/util/uri_test.cc | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 14 deletions(-) diff --git a/dali/util/uri.cc b/dali/util/uri.cc index d2f3f9e20a0..8a3b3862f99 100644 --- a/dali/util/uri.cc +++ b/dali/util/uri.cc @@ -104,7 +104,7 @@ URI URI::Parse(std::string uri, URI::ParseOpts opts) { if (*p == '/' && *(p + 1) == '/') { p += 2; parsed.authority_start_ = p - p_start; - while (*p != '\0' && *p != '/') { + while (*p != '\0' && *p != '/' && *p != '?' && *p != '#') { if (!allowed_char(*p)) { parsed.valid_ = false; parsed.err_msg_ = "Invalid character found (" + display_char(*p) + ") in authority"; @@ -123,7 +123,7 @@ URI URI::Parse(std::string uri, URI::ParseOpts opts) { // Path parsed.path_start_ = p - p_start; - while (*p != '\0' && *p != '?') { + while (*p != '\0' && *p != '?' && *p != '#') { if (!allowed_char(*p) && !allow_non_escaped) { parsed.valid_ = false; parsed.err_msg_ = "Invalid character found (" + display_char(*p) + ") in path"; @@ -135,20 +135,22 @@ URI URI::Parse(std::string uri, URI::ParseOpts opts) { if (*p == '\0') return parsed; - // Query - p++; - parsed.query_start_ = p - p_start; - while (*p != '\0' && *p != '#') { - if (!allowed_char(*p) && !allow_non_escaped) { - parsed.valid_ = false; - parsed.err_msg_ = "Invalid character found (" + display_char(*p) + ") in query"; - return parsed; - } + if (*p == '?') { + // Query p++; + parsed.query_start_ = p - p_start; + while (*p != '\0' && *p != '#') { + if (!allowed_char(*p) && !allow_non_escaped) { + parsed.valid_ = false; + parsed.err_msg_ = "Invalid character found (" + display_char(*p) + ") in query"; + return parsed; + } + p++; + } + parsed.query_end_ = p - p_start; + if (*p == '\0') + return parsed; } - parsed.query_end_ = p - p_start; - if (*p == '\0') - return parsed; // Fragment p++; diff --git a/dali/util/uri_test.cc b/dali/util/uri_test.cc index 5c71bd7d872..4a732d6e37f 100644 --- a/dali/util/uri_test.cc +++ b/dali/util/uri_test.cc @@ -94,6 +94,46 @@ TEST(URI, Parse_7) { EXPECT_EQ("", uri.fragment()); } +TEST(URI, Parse_FragmentWithoutQuery) { + auto uri = URI::Parse("s3://bucket/path#fragment"); + EXPECT_EQ("s3", uri.scheme()); + EXPECT_EQ("bucket", uri.authority()); + EXPECT_EQ("/path", uri.path()); + EXPECT_EQ("", uri.query()); + EXPECT_EQ("/path", uri.path_and_query()); + EXPECT_EQ("fragment", uri.fragment()); +} + +TEST(URI, Parse_EmptyQueryWithFragment) { + auto uri = URI::Parse("s3://bucket/path?#fragment"); + EXPECT_EQ("s3", uri.scheme()); + EXPECT_EQ("bucket", uri.authority()); + EXPECT_EQ("/path", uri.path()); + EXPECT_EQ("", uri.query()); + EXPECT_EQ("/path?", uri.path_and_query()); + EXPECT_EQ("fragment", uri.fragment()); +} + +TEST(URI, Parse_EmptyPathWithFragment) { + auto uri = URI::Parse("s3://bucket#fragment"); + EXPECT_EQ("s3", uri.scheme()); + EXPECT_EQ("bucket", uri.authority()); + EXPECT_EQ("", uri.path()); + EXPECT_EQ("", uri.query()); + EXPECT_EQ("", uri.path_and_query()); + EXPECT_EQ("fragment", uri.fragment()); +} + +TEST(URI, Parse_EmptyPathWithQueryAndFragment) { + auto uri = URI::Parse("s3://bucket?query#fragment"); + EXPECT_EQ("s3", uri.scheme()); + EXPECT_EQ("bucket", uri.authority()); + EXPECT_EQ("", uri.path()); + EXPECT_EQ("query", uri.query()); + EXPECT_EQ("?query", uri.path_and_query()); + EXPECT_EQ("fragment", uri.fragment()); +} + TEST(URI, Parse_Error1) { auto uri = URI::Parse( "telnet://192. 0.2.16:80/");