From 0355391e34190014e3a19596024f26e19224777f Mon Sep 17 00:00:00 2001 From: Jason Volk Date: Thu, 13 Jun 2019 20:06:05 -0600 Subject: [PATCH] ircd::rfc3986: Complete the URI grammars as specified. --- include/ircd/rfc3986.h | 31 ++++++- ircd/rfc3986.cc | 194 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 223 insertions(+), 2 deletions(-) diff --git a/include/ircd/rfc3986.h b/include/ircd/rfc3986.h index 8e729e8cf..32f2e411e 100644 --- a/include/ircd/rfc3986.h +++ b/include/ircd/rfc3986.h @@ -49,8 +49,26 @@ struct ircd::rfc3986::parser template using rule = boost::spirit::qi::rule; - // note in all examples that portnums are always optional - static const rule port; + static const rule<> sub_delims; + static const rule<> gen_delims; + static const rule<> reserved; + static const rule<> unreserved; + static const rule<> pct_encoded; + static const rule<> pchar; + static const rule<> query; + static const rule<> fragment; + static const rule<> segment; + static const rule<> segment_nz; + static const rule<> segment_nz_nc; + static const rule<> path_rootless; + static const rule<> path_noscheme; + static const rule<> path_absolute; + static const rule<> path_abempty; + static const rule<> path; + static const rule<> reg_name; + static const rule<> userinfo; + + static const rule port; // note in examples portnums are optional static const rule<> ip4_octet; static const rule<> ip4_address; // 1.2.3.4 @@ -79,6 +97,15 @@ struct ircd::rfc3986::parser static const rule<> host_literal; // 1.2.3.4 | [::1] | foo.com static const rule<> remote; // 1.2.3.4:12345 | [::1]:12345 | foo.com:12345 + + static const rule<> authority; + static const rule<> scheme; + static const rule<> hier_part; + static const rule<> relative_part; + static const rule<> relative_ref; + static const rule<> absolute_uri; + static const rule<> uri; + static const rule<> uri_ref; // uri | relative_ref }; // Validator suite diff --git a/ircd/rfc3986.cc b/ircd/rfc3986.cc index 04b110f64..fe30ad670 100644 --- a/ircd/rfc3986.cc +++ b/ircd/rfc3986.cc @@ -68,6 +68,136 @@ struct ircd::rfc3986::decoder } const ircd::rfc3986::decoder; +decltype(ircd::rfc3986::parser::sub_delims) +ircd::rfc3986::parser::sub_delims +{ + lit('!') | lit('$') | lit('&') | lit('\'') | + lit('(') | lit(')') | lit('*') | lit('+') | + lit(',') | lit(';') | lit('=') + ,"sub-delims" +}; + +decltype(ircd::rfc3986::parser::gen_delims) +ircd::rfc3986::parser::gen_delims +{ + lit(':') | lit('/') | lit('?') | lit('#') | + lit('[') | lit(']') | lit('@') + ,"gen-delims" +}; + +decltype(ircd::rfc3986::parser::unreserved) +ircd::rfc3986::parser::unreserved +{ + ascii::alpha | ascii::digit | + lit('-') | lit('.') | lit('_') | lit('~') + ,"reserved" +}; + +decltype(ircd::rfc3986::parser::reserved) +ircd::rfc3986::parser::reserved +{ + gen_delims | sub_delims + ,"reserved" +}; + +decltype(ircd::rfc3986::parser::pct_encoded) +ircd::rfc3986::parser::pct_encoded +{ + lit('%') >> repeat(2)[ascii::xdigit] + ,"pct-encoded" +}; + +decltype(ircd::rfc3986::parser::pchar) +ircd::rfc3986::parser::pchar +{ + unreserved | pct_encoded | sub_delims | lit(':') | lit('@') + ,"pchar" +}; + +decltype(ircd::rfc3986::parser::query) +ircd::rfc3986::parser::query +{ + *(pchar | lit('/') | lit('?')) + ,"query" +}; + +decltype(ircd::rfc3986::parser::fragment) +ircd::rfc3986::parser::fragment +{ + *(pchar | lit('/') | lit('?')) + ,"fragment" +}; + +decltype(ircd::rfc3986::parser::segment_nz_nc) +ircd::rfc3986::parser::segment_nz_nc +{ + +(unreserved | pct_encoded | sub_delims | lit('@')) + ,"segment-nz-nc" +}; + +decltype(ircd::rfc3986::parser::segment_nz) +ircd::rfc3986::parser::segment_nz +{ + +pchar + ,"segment-nz" +}; + +decltype(ircd::rfc3986::parser::segment) +ircd::rfc3986::parser::segment +{ + *pchar + ,"segment" +}; + +decltype(ircd::rfc3986::parser::path_abempty) +ircd::rfc3986::parser::path_abempty +{ + *(lit('/') >> segment) + ,"path-abempty" +}; + +decltype(ircd::rfc3986::parser::path_noscheme) +ircd::rfc3986::parser::path_noscheme +{ + segment_nz_nc >> *(lit('/') >> segment) + ,"path-noscheme" +}; + +decltype(ircd::rfc3986::parser::path_rootless) +ircd::rfc3986::parser::path_rootless +{ + segment_nz >> *(lit('/') >> segment) + ,"path-rootless" +}; + +decltype(ircd::rfc3986::parser::path_absolute) +ircd::rfc3986::parser::path_absolute +{ + lit('/') >> -(path_rootless) + ,"path-absolute" +}; + +decltype(ircd::rfc3986::parser::path) +ircd::rfc3986::parser::path +{ + -(path_abempty | path_absolute | path_noscheme | path_rootless) + ,"path" +}; + +decltype(ircd::rfc3986::parser::reg_name) +ircd::rfc3986::parser::reg_name +{ + *(unreserved | pct_encoded | sub_delims) + ,"reg-name" +}; + +decltype(ircd::rfc3986::parser::userinfo) +ircd::rfc3986::parser::userinfo +{ + *(unreserved | pct_encoded | sub_delims | lit(':')) + ,"userinfo" +}; + decltype(ircd::rfc3986::parser::port) ircd::rfc3986::parser::port { @@ -240,6 +370,66 @@ ircd::rfc3986::parser::remote ,"remote" }; +decltype(ircd::rfc3986::parser::authority) +ircd::rfc3986::parser::authority +{ + -(userinfo >> lit('@')) >> remote + ,"authority" +}; + +decltype(ircd::rfc3986::parser::scheme) +ircd::rfc3986::parser::scheme +{ + ascii::alpha >> *(ascii::alnum | lit('+') | lit('-') | lit('.')) + ,"scheme" +}; + +decltype(ircd::rfc3986::parser::hier_part) +ircd::rfc3986::parser::hier_part +{ + -((lit("//") >> authority >> path_abempty) | path_absolute | path_rootless) + ,"hier_part" +}; + +decltype(ircd::rfc3986::parser::relative_part) +ircd::rfc3986::parser::relative_part +{ + -((lit("//") >> authority >> path_abempty) | path_absolute | path_noscheme) + ,"relative-part" +}; + +decltype(ircd::rfc3986::parser::relative_ref) +ircd::rfc3986::parser::relative_ref +{ + relative_part >> -(lit('?') >> query) >> -(lit('#') >> fragment) + ,"relative-ref" +}; + +decltype(ircd::rfc3986::parser::absolute_uri) +ircd::rfc3986::parser::absolute_uri +{ + scheme >> lit(':') >> hier_part >> -(lit('?') >> query) + ,"absolute-URI" +}; + +decltype(ircd::rfc3986::parser::uri) +ircd::rfc3986::parser::uri +{ + scheme >> lit(':') >> hier_part >> -(lit('?') >> query) >> -(lit('#') >> fragment) + ,"URI" +}; + +decltype(ircd::rfc3986::parser::uri_ref) +ircd::rfc3986::parser::uri_ref +{ + uri | relative_ref + ,"URI-reference" +}; + +// +// general interface +// + ircd::string_view ircd::rfc3986::encode(const mutable_buffer &out, const json::members &members) @@ -383,6 +573,10 @@ catch(const qi::expectation_failure &e) throw expectation_failure{e}; } +// +// validators +// + bool ircd::rfc3986::valid_remote(std::nothrow_t, const string_view &str)