diff --git a/src/uri/uri.cc b/src/uri/uri.cc index dd06f9608..1ae7c08b7 100644 --- a/src/uri/uri.cc +++ b/src/uri/uri.cc @@ -236,7 +236,13 @@ auto URI::host() const -> std::optional { auto URI::port() const -> std::optional { return this->port_; } auto URI::path() const -> std::optional { + // NOTE: This is a workaround for the fact that `uriparser` does not + // parse /.. as a segment, then we store nothing in the path_ field. + // By that we can't add the initial slash to the URI. if (!this->path_.has_value()) { + if (this->data == "/..") { + return "/"; + } return std::nullopt; } diff --git a/test/uri/uri_normalize_test.cc b/test/uri/uri_normalize_test.cc index 3e65ad25d..5db5b6cb4 100644 --- a/test/uri/uri_normalize_test.cc +++ b/test/uri/uri_normalize_test.cc @@ -88,3 +88,46 @@ TEST(URI_normalize, relative_path_9) { const sourcemeta::jsontoolkit::URI uri{"./abc:def"}; EXPECT_EQ(uri.recompose(), "./abc:def"); } + +// Inspired from +// https://github.com/uriparser/uriparser/blob/master/test/test.cpp#L1531 + +TEST(URI_normalize, path_1) { + const sourcemeta::jsontoolkit::URI uri{"http://a/b/c/../../.."}; + EXPECT_EQ(uri.recompose(), "http://a/"); +} + +TEST(URI_normalize, path_2) { + const sourcemeta::jsontoolkit::URI uri{"http://a/b/../c/../.."}; + EXPECT_EQ(uri.recompose(), "http://a/"); +} + +TEST(URI_normalize, path_3) { + const sourcemeta::jsontoolkit::URI uri{"http://a/.."}; + EXPECT_EQ(uri.recompose(), "http://a/"); +} + +TEST(URI_normalize, path_4) { + const sourcemeta::jsontoolkit::URI uri{"/.."}; + EXPECT_EQ(uri.recompose(), "/"); +} + +TEST(URI_normalize, path_5) { + const sourcemeta::jsontoolkit::URI uri{"http://a/..///"}; + EXPECT_EQ(uri.recompose(), "http://a///"); +} + +TEST(URI_normalize, path_6) { + const sourcemeta::jsontoolkit::URI uri{"http://a/..///.."}; + EXPECT_EQ(uri.recompose(), "http://a//"); +} + +TEST(URI_normalize, path_7) { + const sourcemeta::jsontoolkit::URI uri{"a/b/c/../../.."}; + EXPECT_EQ(uri.recompose(), ""); +} + +TEST(URI_normalize, path_8) { + const sourcemeta::jsontoolkit::URI uri{"a/b/../../c/.."}; + EXPECT_EQ(uri.recompose(), ""); +}