mirror of
https://github.com/matrix-construct/construct
synced 2024-11-29 18:22:50 +01:00
ircd::rfc3986: Move encoder/decoder into parser ns; fix karma::grammar.
This commit is contained in:
parent
398c1d2213
commit
0c281f10d0
1 changed files with 40 additions and 61 deletions
101
ircd/rfc3986.cc
101
ircd/rfc3986.cc
|
@ -8,16 +8,6 @@
|
||||||
// copyright notice and this permission notice is present in all copies. The
|
// copyright notice and this permission notice is present in all copies. The
|
||||||
// full license for this software is available in the LICENSE file.
|
// full license for this software is available in the LICENSE file.
|
||||||
|
|
||||||
#pragma GCC visibility push(internal)
|
|
||||||
namespace ircd::rfc3986
|
|
||||||
{
|
|
||||||
using namespace ircd::spirit;
|
|
||||||
|
|
||||||
struct encoder extern const encoder;
|
|
||||||
struct decoder extern const decoder;
|
|
||||||
}
|
|
||||||
#pragma GCC visibility pop
|
|
||||||
|
|
||||||
namespace ircd::rfc3986::parser
|
namespace ircd::rfc3986::parser
|
||||||
{
|
{
|
||||||
using namespace ircd::spirit;
|
using namespace ircd::spirit;
|
||||||
|
@ -433,56 +423,62 @@ ircd::rfc3986::uri::uri(const string_view &input)
|
||||||
// uri decoding
|
// uri decoding
|
||||||
//
|
//
|
||||||
|
|
||||||
struct [[gnu::visibility("internal")]]
|
namespace ircd::rfc3986::parser::decoder
|
||||||
ircd::rfc3986::decoder
|
|
||||||
{
|
{
|
||||||
template<class R = unused_type,
|
template<class R = unused_type,
|
||||||
class... S>
|
class... S>
|
||||||
using rule = qi::rule<const char *, R, S...>;
|
struct [[gnu::visibility("internal")]] rule
|
||||||
|
:qi::rule<const char *, R, S...>
|
||||||
[[noreturn]] static void throw_unsafe()
|
|
||||||
{
|
{
|
||||||
throw decoding_error
|
using qi::rule<const char *, R, S...>::rule;
|
||||||
|
};
|
||||||
|
|
||||||
|
static const auto is_safe
|
||||||
|
{
|
||||||
|
[](const char val, auto &c, bool &pass)
|
||||||
{
|
{
|
||||||
"Unsafe characters in decoding."
|
pass = (val > 0x1F) | (val < 0x00);
|
||||||
};
|
attr_at<0>(c) = val;
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const rule<char()> decode_char
|
const expr decode_char
|
||||||
{
|
{
|
||||||
lit('%') > qi::uint_parser<unsigned char, 16, 2, 2>{}
|
lit('%') > qi::int_parser<char, 16, 2, 2>{}
|
||||||
,"url decodable character"
|
,"url decodable character"
|
||||||
};
|
};
|
||||||
|
|
||||||
const rule<char()> unreserved_char
|
const rule<char()> decode_char_safe
|
||||||
{
|
{
|
||||||
// unreserved characters and !$+*'(),
|
lit('%') > qi::int_parser<char, 16, 2, 2>{}[is_safe]
|
||||||
//char_("A-Za-z0-9._~!$+*'(),-")
|
,"url decodable character"
|
||||||
|
};
|
||||||
|
|
||||||
|
const expr unreserved_char
|
||||||
|
{
|
||||||
|
//char_("A-Za-z0-9._~!$+*'(),-")
|
||||||
//NOTE: allow any non-control character here. No reason for trouble with
|
//NOTE: allow any non-control character here. No reason for trouble with
|
||||||
//NOTE: already-decoded inputs unless some other grammar expects it.
|
//NOTE: already-decoded inputs unless some other grammar expects it.
|
||||||
(~ascii::cntrl) - '%'
|
(~ascii::cntrl) - '%'
|
||||||
,"url unreserved characters"
|
,"url unreserved characters"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const rule<mutable_buffer> decode_safe
|
||||||
|
{
|
||||||
|
*(unreserved_char | decode_char_safe)
|
||||||
|
,"url safe decode"
|
||||||
|
};
|
||||||
|
|
||||||
const rule<mutable_buffer> decode_unsafe
|
const rule<mutable_buffer> decode_unsafe
|
||||||
{
|
{
|
||||||
*((char_ - '%') | decode_char)
|
*((char_ - '%') | decode_char)
|
||||||
,"url unsafe decode"
|
,"url unsafe decode"
|
||||||
};
|
};
|
||||||
|
|
||||||
rule<mutable_buffer> decode_safe
|
|
||||||
{
|
|
||||||
*(unreserved_char | decode_char[_pass = ((local::_1 > 0x1F) | (local::_1 < 0x00))])
|
|
||||||
,"url safe decode"
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
const ircd::rfc3986::decoder;
|
|
||||||
|
|
||||||
ircd::const_buffer
|
ircd::const_buffer
|
||||||
ircd::rfc3986::decode_unsafe(const mutable_buffer &buf,
|
ircd::rfc3986::decode_unsafe(const mutable_buffer &buf,
|
||||||
const string_view &url)
|
const string_view &url)
|
||||||
try
|
|
||||||
{
|
{
|
||||||
const char *start(url.data()), *const stop
|
const char *start(url.data()), *const stop
|
||||||
{
|
{
|
||||||
|
@ -496,7 +492,7 @@ try
|
||||||
|
|
||||||
const bool ok
|
const bool ok
|
||||||
{
|
{
|
||||||
ircd::parse(start, stop, decoder.decode_unsafe, mb)
|
ircd::parse(std::nothrow, start, stop, parser::decoder::decode_unsafe, mb)
|
||||||
};
|
};
|
||||||
|
|
||||||
assert(size(mb) <= size(url));
|
assert(size(mb) <= size(url));
|
||||||
|
@ -505,15 +501,10 @@ try
|
||||||
data(mb), size(mb)
|
data(mb), size(mb)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
catch(const qi::expectation_failure<const char *> &e)
|
|
||||||
{
|
|
||||||
throw expectation_failure<decoding_error>{e};
|
|
||||||
}
|
|
||||||
|
|
||||||
ircd::string_view
|
ircd::string_view
|
||||||
ircd::rfc3986::decode(const mutable_buffer &buf,
|
ircd::rfc3986::decode(const mutable_buffer &buf,
|
||||||
const string_view &url)
|
const string_view &url)
|
||||||
try
|
|
||||||
{
|
{
|
||||||
const char *start(url.data()), *const stop
|
const char *start(url.data()), *const stop
|
||||||
{
|
{
|
||||||
|
@ -527,7 +518,7 @@ try
|
||||||
|
|
||||||
const bool ok
|
const bool ok
|
||||||
{
|
{
|
||||||
ircd::parse(start, stop, decoder.decode_safe, mb)
|
ircd::parse<decoding_error>(start, stop, parser::decoder::decode_safe, mb)
|
||||||
};
|
};
|
||||||
|
|
||||||
assert(size(mb) <= size(url));
|
assert(size(mb) <= size(url));
|
||||||
|
@ -536,22 +527,20 @@ try
|
||||||
data(mb), size(mb)
|
data(mb), size(mb)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
catch(const qi::expectation_failure<const char *> &e)
|
|
||||||
{
|
|
||||||
throw expectation_failure<decoding_error>{e};
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// uri encoding
|
// uri encoding
|
||||||
//
|
//
|
||||||
|
|
||||||
struct [[gnu::visibility("internal")]]
|
namespace ircd::rfc3986::parser::encoder
|
||||||
ircd::rfc3986::encoder
|
|
||||||
:karma::grammar<char *, string_view>
|
|
||||||
{
|
{
|
||||||
template<class R = unused_type,
|
template<class R = unused_type,
|
||||||
class... S>
|
class... S>
|
||||||
using rule = karma::rule<char *, R, S...>;
|
struct [[gnu::visibility("internal")]] rule
|
||||||
|
:karma::rule<char *, R, S...>
|
||||||
|
{
|
||||||
|
using karma::rule<char *, R, S...>::rule;
|
||||||
|
};
|
||||||
|
|
||||||
const rule<char()> unreserved
|
const rule<char()> unreserved
|
||||||
{
|
{
|
||||||
|
@ -564,12 +553,7 @@ ircd::rfc3986::encoder
|
||||||
*(unreserved | (lit('%') << karma::right_align(2, '0')[karma::upper[karma::hex]]))
|
*(unreserved | (lit('%') << karma::right_align(2, '0')[karma::upper[karma::hex]]))
|
||||||
,"url encode"
|
,"url encode"
|
||||||
};
|
};
|
||||||
|
|
||||||
encoder()
|
|
||||||
:encoder::base_type{encode}
|
|
||||||
{}
|
|
||||||
}
|
}
|
||||||
const ircd::rfc3986::encoder;
|
|
||||||
|
|
||||||
ircd::string_view
|
ircd::string_view
|
||||||
ircd::rfc3986::encode(const mutable_buffer &out,
|
ircd::rfc3986::encode(const mutable_buffer &out,
|
||||||
|
@ -616,7 +600,7 @@ ircd::rfc3986::encode(const mutable_buffer &buf_,
|
||||||
|
|
||||||
const bool ok
|
const bool ok
|
||||||
{
|
{
|
||||||
ircd::generate(buf, encoder, url)
|
ircd::generate(buf, parser::encoder::encode, url)
|
||||||
};
|
};
|
||||||
|
|
||||||
return string_view
|
return string_view
|
||||||
|
@ -802,7 +786,7 @@ ircd::rfc3986::valid(std::nothrow_t,
|
||||||
{
|
{
|
||||||
const parser::rule<> only_rule
|
const parser::rule<> only_rule
|
||||||
{
|
{
|
||||||
rule >> eoi
|
rule >> parser::eoi
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *start(str.data()), *const stop(start + str.size());
|
const char *start(str.data()), *const stop(start + str.size());
|
||||||
|
@ -812,17 +796,12 @@ ircd::rfc3986::valid(std::nothrow_t,
|
||||||
void
|
void
|
||||||
ircd::rfc3986::valid(const parser::rule<> &rule,
|
ircd::rfc3986::valid(const parser::rule<> &rule,
|
||||||
const string_view &str)
|
const string_view &str)
|
||||||
try
|
|
||||||
{
|
{
|
||||||
const parser::rule<> only_rule
|
const parser::rule<> only_rule
|
||||||
{
|
{
|
||||||
eps > (rule >> eoi)
|
parser::eps > (rule >> parser::eoi)
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *start(str.data()), *const stop(start + str.size());
|
const char *start(str.data()), *const stop(start + str.size());
|
||||||
ircd::parse(start, stop, only_rule);
|
ircd::parse<error>(start, stop, only_rule);
|
||||||
}
|
|
||||||
catch(const qi::expectation_failure<const char *> &e)
|
|
||||||
{
|
|
||||||
throw expectation_failure<error>{e};
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue