diff --git a/include/ircd/rfc3986.h b/include/ircd/rfc3986.h index 56bd92824..8e1df212f 100644 --- a/include/ircd/rfc3986.h +++ b/include/ircd/rfc3986.h @@ -28,6 +28,8 @@ namespace ircd::rfc3986 void valid_hostname(const string_view &); // name part bool valid_hostname(std::nothrow_t, const string_view &); + void valid_literal(const string_view &); // ip4 | ip6 + bool valid_literal(std::nothrow_t, const string_view &); void valid_domain(const string_view &); // dot delimited hostnames bool valid_domain(std::nothrow_t, const string_view &); void valid_host(const string_view &); // domain | ip4 | ip6 diff --git a/ircd/rfc3986.cc b/ircd/rfc3986.cc index 39d3d02d5..878c95ada 100644 --- a/ircd/rfc3986.cc +++ b/ircd/rfc3986.cc @@ -428,6 +428,38 @@ catch(const qi::expectation_failure &e) throw expectation_failure{e}; } +bool +ircd::rfc3986::valid_literal(std::nothrow_t, + const string_view &str) +{ + static const auto &rule + { + (parser::ip6_literal >> eoi) | + (parser::ip4_literal >> eoi) + }; + + const char *start(str.data()), *const stop(start + str.size()); + return qi::parse(start, stop, rule); +} + +void +ircd::rfc3986::valid_literal(const string_view &str) +try +{ + static const auto &rule + { + (parser::ip6_literal >> eoi) | + (parser::ip4_literal >> eoi) + }; + + const char *start(str.data()), *const stop(start + str.size()); + qi::parse(start, stop, eps > rule); +} +catch(const qi::expectation_failure &e) +{ + throw expectation_failure{e}; +} + bool ircd::rfc3986::valid_hostname(std::nothrow_t, const string_view &str)