Skip to content

Commit ef23a63

Browse files
authored
Fix URI::resolve_from when dealing with file bases (#1797)
Signed-off-by: Juan Cruz Viotti <jv@jviotti.com>
1 parent 64cd14e commit ef23a63

File tree

2 files changed

+24
-2
lines changed

2 files changed

+24
-2
lines changed

src/core/uri/uri.cc

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -556,17 +556,24 @@ auto URI::canonicalize() -> URI & {
556556
}
557557

558558
auto URI::resolve_from(const URI &base) -> URI & {
559+
const bool is_file{base.scheme_ == "file"};
560+
auto copy = base;
561+
if (is_file) {
562+
// Huge hack, but otherwise `uriparser` will resolve in a weird way
563+
copy.host_ = "placeholder";
564+
}
565+
559566
UriUriA absoluteDest;
560567
// Looks like this function allocates to the output variable
561568
// even on failure.
562569
// See https://uriparser.github.io/doc/api/latest/
563570
switch (uriAddBaseUriExA(&absoluteDest, &this->internal->uri,
564-
&base.internal->uri, URI_RESOLVE_STRICTLY)) {
571+
&copy.internal->uri, URI_RESOLVE_STRICTLY)) {
565572
case URI_SUCCESS:
566573
break;
567574
case URI_ERROR_ADDBASE_REL_BASE:
568575
uriFreeUriMembersA(&absoluteDest);
569-
assert(!base.is_absolute());
576+
assert(!copy.is_absolute());
570577
throw URIError{"Base URI is not absolute"};
571578
default:
572579
uriFreeUriMembersA(&absoluteDest);

test/uri/uri_resolve_from_test.cc

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,3 +108,18 @@ TEST(URI_resolve_from, rfc3986_resolve_with_absolute_path) {
108108
absolute_path.resolve_from(base);
109109
EXPECT_EQ(absolute_path.recompose(), "s://h/x");
110110
}
111+
112+
TEST(URI_resolve_from, file_1) {
113+
const sourcemeta::core::URI base{"file:///foo/bar/baz"};
114+
sourcemeta::core::URI relative{"./qux"};
115+
relative.resolve_from(base);
116+
EXPECT_EQ(relative.recompose(), "file:///foo/bar/qux");
117+
}
118+
119+
TEST(URI_resolve_from, file_from_path) {
120+
const std::filesystem::path base_path{"/foo/bar/baz"};
121+
const auto base{sourcemeta::core::URI::from_path(base_path)};
122+
sourcemeta::core::URI relative{"./qux"};
123+
relative.resolve_from(base);
124+
EXPECT_EQ(relative.recompose(), "file:///foo/bar/qux");
125+
}

0 commit comments

Comments
 (0)