Skip to content

Commit

Permalink
Disallow null characters in URL <-> path conversions
Browse files Browse the repository at this point in the history
Check for null characters in url_from_file_path and path_from_file_url
functions.
  • Loading branch information
rmisev committed Nov 23, 2023
1 parent fcaaaa1 commit 357f370
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 0 deletions.
9 changes: 9 additions & 0 deletions include/upa/url.h
Original file line number Diff line number Diff line change
Expand Up @@ -3090,6 +3090,10 @@ inline url url_from_file_path(StrT&& str, file_path_format format = file_path_fo
}
}

// Check for null characters
if (util::contains_null(pointer, last))
throw url_error(validation_errc::null_character, "Path contains null character");

// make URL
detail::append_utf8_percent_encoded(pointer, last, *no_encode_set, str_url);
return url(str_url);
Expand Down Expand Up @@ -3164,6 +3168,11 @@ inline std::string path_from_file_url(const url& file_url, file_path_format form
}
}
}

// Check for null characters
if (util::contains_null(path.begin(), path.end()))
throw url_error(validation_errc::null_character, "Path contains null character");

return path;
}

Expand Down
1 change: 1 addition & 0 deletions include/upa/url_result.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ enum class validation_errc {
file_url_unsupported_host, ///< UNC path cannot have "." hostname
file_url_invalid_unc, ///< Invalid UNC path in file URL
file_url_not_windows_path, ///< Not a Windows path in file URL
null_character, ///< Path contains null character
};

/// @brief Check validation error code indicates success
Expand Down
5 changes: 5 additions & 0 deletions include/upa/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,11 @@ inline void append_ascii_lowercase(std::string& dest, const CharT* first, const

// Finders

template <class InputIt>
inline bool contains_null(InputIt first, InputIt last) {
return std::find(first, last, '\0') != last;
}

template <class CharT>
UPA_CONSTEXPR_17 bool has_xn_label(const CharT* first, const CharT* last) {
if (last - first >= 4) {
Expand Down
8 changes: 8 additions & 0 deletions test/test-url.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -605,6 +605,8 @@ TEST_CASE("url_from_file_path") {
// non absolute path
CHECK_THROWS_AS(upa::url_from_file_path("path"), upa::url_error);
CHECK_THROWS_AS(upa::url_from_file_path("\\\\h\\p", upa::file_path_format::posix), upa::url_error);
// null character
CHECK_THROWS_AS(upa::url_from_file_path(std::string{ "/p\0", 3 }, upa::file_path_format::posix), upa::url_error);
}
SUBCASE("Windows path") {
// https://learn.microsoft.com/en-us/windows/win32/fileio/naming-a-file
Expand Down Expand Up @@ -644,6 +646,8 @@ TEST_CASE("url_from_file_path") {
// unsupported pathes
CHECK_THROWS_AS(upa::url_from_file_path("\\\\?\\Volume{b75e2c83-0000-0000-0000-602f00000000}\\Test\\Foo.txt"), upa::url_error);
CHECK_THROWS_AS(upa::url_from_file_path("\\\\.\\Volume{b75e2c83-0000-0000-0000-602f00000000}\\Test\\Foo.txt"), upa::url_error);
// null character
CHECK_THROWS_AS(upa::url_from_file_path(std::string{ "/C:/p\0", 6 }, upa::file_path_format::posix), upa::url_error);
}
}

Expand All @@ -660,6 +664,8 @@ TEST_CASE("path_from_file_url") {
CHECK(path_from_file_url("file:///path", upa::file_path_format::posix) == "/path");
// POSIX path cannot have host
CHECK_THROWS_AS(path_from_file_url("file://host/path", upa::file_path_format::posix), upa::url_error);
// null character
CHECK_THROWS_AS(path_from_file_url("file:///p%00", upa::file_path_format::posix), upa::url_error);
}
SUBCASE("Windows path") {
CHECK(path_from_file_url("file:///C:", upa::file_path_format::windows) == "C:\\");
Expand All @@ -685,6 +691,8 @@ TEST_CASE("path_from_file_url") {
CHECK_THROWS_AS(path_from_file_url("file://///host/", upa::file_path_format::windows), upa::url_error);
// Unsupported "." hostname
CHECK_THROWS_AS(path_from_file_url("file://./name", upa::file_path_format::windows), upa::url_error);
// null character
CHECK_THROWS_AS(path_from_file_url("file:///C:/p%00", upa::file_path_format::posix), upa::url_error);
}
SUBCASE("Native path") {
#ifdef _WIN32
Expand Down

0 comments on commit 357f370

Please sign in to comment.