Fix #2173 with a no_trailing_dot_policy
no_trailing_dot_policy rejects parsing exp, exp_n, nan, inf and rejects parsing a fractional part if detects ".Fmt". For Fmt = 'j', 's', 'o', 'n': 42.foo rule parses 42. 42.json rule parses 42 42..json rule parses 42. Reference: - https://github.com/Project-OSRM/osrm-backend/pull/2222#issuecomment-206206239
This commit is contained in:
parent
cae06ba2c1
commit
58ebadd7b3
@ -29,10 +29,51 @@ namespace api
|
|||||||
{
|
{
|
||||||
|
|
||||||
namespace qi = boost::spirit::qi;
|
namespace qi = boost::spirit::qi;
|
||||||
|
|
||||||
|
template <typename T, char... Fmt>
|
||||||
|
struct no_trailing_dot_policy : qi::real_policies<T> {
|
||||||
|
|
||||||
|
template <typename Iterator>
|
||||||
|
static bool parse_dot(Iterator& first, Iterator const& last) {
|
||||||
|
if (first == last || *first != '.')
|
||||||
|
return false;
|
||||||
|
|
||||||
|
static const constexpr char fmt[sizeof...(Fmt)] = {Fmt...};
|
||||||
|
|
||||||
|
if (first + sizeof(fmt) < last
|
||||||
|
&& std::equal(fmt, fmt + sizeof(fmt), first + 1u))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
++first;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Iterator>
|
||||||
|
static bool parse_exp(Iterator&, const Iterator&) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Iterator, typename Attribute>
|
||||||
|
static bool parse_exp_n(Iterator&, const Iterator&, Attribute&) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Iterator, typename Attribute>
|
||||||
|
static bool parse_nan(Iterator&, const Iterator&, Attribute&) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Iterator, typename Attribute>
|
||||||
|
static bool parse_inf(Iterator&, const Iterator&, Attribute&) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
struct BaseParametersGrammar : boost::spirit::qi::grammar<std::string::iterator>
|
struct BaseParametersGrammar : boost::spirit::qi::grammar<std::string::iterator>
|
||||||
{
|
{
|
||||||
using Iterator = std::string::iterator;
|
using Iterator = std::string::iterator;
|
||||||
using RadiusesT = std::vector<boost::optional<double>>;
|
using RadiusesT = std::vector<boost::optional<double>>;
|
||||||
|
using json_policy = no_trailing_dot_policy<double, 'j', 's', 'o', 'n'>;
|
||||||
|
|
||||||
BaseParametersGrammar(qi::rule<Iterator> &root_rule_, engine::api::BaseParameters ¶meters_)
|
BaseParametersGrammar(qi::rule<Iterator> &root_rule_, engine::api::BaseParameters ¶meters_)
|
||||||
: BaseParametersGrammar::base_type(root_rule_), base_parameters(parameters_)
|
: BaseParametersGrammar::base_type(root_rule_), base_parameters(parameters_)
|
||||||
@ -82,7 +123,7 @@ struct BaseParametersGrammar : boost::spirit::qi::grammar<std::string::iterator>
|
|||||||
qi::lit("bearings=") >> (-(qi::short_ >> ',' >> qi::short_))[add_bearing] % ";";
|
qi::lit("bearings=") >> (-(qi::short_ >> ',' >> qi::short_))[add_bearing] % ";";
|
||||||
polyline_rule = qi::as_string[qi::lit("polyline(") >> +polyline_chars >>
|
polyline_rule = qi::as_string[qi::lit("polyline(") >> +polyline_chars >>
|
||||||
qi::lit(")")][polyline_to_coordinates];
|
qi::lit(")")][polyline_to_coordinates];
|
||||||
location_rule = (qi::double_ >> qi::lit(',') >> qi::double_)[add_coordinate];
|
location_rule = (double_ >> qi::lit(',') >> double_)[add_coordinate];
|
||||||
query_rule = (location_rule % ';') | polyline_rule;
|
query_rule = (location_rule % ';') | polyline_rule;
|
||||||
|
|
||||||
base_rule = bearings_rule | radiuses_rule[set_radiuses] | hints_rule;
|
base_rule = bearings_rule | radiuses_rule[set_radiuses] | hints_rule;
|
||||||
@ -100,6 +141,7 @@ struct BaseParametersGrammar : boost::spirit::qi::grammar<std::string::iterator>
|
|||||||
qi::rule<Iterator, RadiusesT()> radiuses_rule;
|
qi::rule<Iterator, RadiusesT()> radiuses_rule;
|
||||||
qi::rule<Iterator, unsigned char()> base64_char;
|
qi::rule<Iterator, unsigned char()> base64_char;
|
||||||
qi::rule<Iterator, std::string()> alpha_numeral, polyline_chars;
|
qi::rule<Iterator, std::string()> alpha_numeral, polyline_chars;
|
||||||
|
qi::real_parser<double, json_policy> double_;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -62,8 +62,7 @@ struct MatchParametersGrammar final : public BaseParametersGrammar
|
|||||||
timestamps_rule = qi::lit("timestamps=") >> qi::uint_ % ";";
|
timestamps_rule = qi::lit("timestamps=") >> qi::uint_ % ";";
|
||||||
match_rule = steps_rule[set_steps] | geometries_rule | overview_rule |
|
match_rule = steps_rule[set_steps] | geometries_rule | overview_rule |
|
||||||
timestamps_rule[set_timestamps];
|
timestamps_rule[set_timestamps];
|
||||||
root_rule = query_rule >> -qi::lit(".") >> -qi::lit("json") >>
|
root_rule = query_rule >> -qi::lit(".json") >> -(qi::lit("?") >> (match_rule | base_rule) % '&');
|
||||||
-(qi::lit("?") >> (match_rule | base_rule) % '&');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
engine::api::MatchParameters parameters;
|
engine::api::MatchParameters parameters;
|
||||||
|
@ -31,8 +31,7 @@ struct NearestParametersGrammar final : public BaseParametersGrammar
|
|||||||
parameters.number_of_results = number;
|
parameters.number_of_results = number;
|
||||||
};
|
};
|
||||||
nearest_rule = (qi::lit("number=") >> qi::uint_)[set_number];
|
nearest_rule = (qi::lit("number=") >> qi::uint_)[set_number];
|
||||||
root_rule = query_rule >> -qi::lit(".") >> -qi::lit("json") >>
|
root_rule = query_rule >> -qi::lit(".json") >> -(qi::lit("?") >> (nearest_rule | base_rule) % '&');
|
||||||
-(qi::lit("?") >> (nearest_rule | base_rule) % '&');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
engine::api::NearestParameters parameters;
|
engine::api::NearestParameters parameters;
|
||||||
|
@ -65,8 +65,7 @@ struct RouteParametersGrammar : public BaseParametersGrammar
|
|||||||
route_rule = steps_rule[set_steps] | alternatives_rule[set_alternatives] | geometries_rule |
|
route_rule = steps_rule[set_steps] | alternatives_rule[set_alternatives] | geometries_rule |
|
||||||
overview_rule | uturns_rule;
|
overview_rule | uturns_rule;
|
||||||
|
|
||||||
root_rule = query_rule >> -qi::lit(".") >> -qi::lit("json") >>
|
root_rule = query_rule >> -qi::lit(".json") >> -(qi::lit("?") >> (route_rule | base_rule) % '&');
|
||||||
-(qi::lit("?") >> (route_rule | base_rule) % '&');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
engine::api::RouteParameters parameters;
|
engine::api::RouteParameters parameters;
|
||||||
|
@ -41,8 +41,7 @@ struct TableParametersGrammar final : public BaseParametersGrammar
|
|||||||
(qi::lit("sources=") >> (qi::ulong_ % ";")[set_sources]) | qi::lit("sources=all");
|
(qi::lit("sources=") >> (qi::ulong_ % ";")[set_sources]) | qi::lit("sources=all");
|
||||||
table_rule = destinations_rule | sources_rule;
|
table_rule = destinations_rule | sources_rule;
|
||||||
|
|
||||||
root_rule = query_rule >> -qi::lit(".") >> -qi::lit("json") >>
|
root_rule = query_rule >> -qi::lit(".json") >> -(qi::lit("?") >> (table_rule | base_rule) % '&');
|
||||||
-(qi::lit("?") >> (table_rule | base_rule) % '&');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
engine::api::TableParameters parameters;
|
engine::api::TableParameters parameters;
|
||||||
|
@ -57,8 +57,7 @@ struct TripParametersGrammar final : public BaseParametersGrammar
|
|||||||
qi::lit("overview=false")[set_false_type];
|
qi::lit("overview=false")[set_false_type];
|
||||||
trip_rule = steps_rule[set_steps] | geometries_rule | overview_rule;
|
trip_rule = steps_rule[set_steps] | geometries_rule | overview_rule;
|
||||||
|
|
||||||
root_rule = query_rule >> -qi::lit(".") >> -qi::lit("json") >>
|
root_rule = query_rule >> -qi::lit(".json") >> -(qi::lit("?") >> (trip_rule | base_rule) % '&');
|
||||||
-(qi::lit("?") >> (trip_rule | base_rule) % '&');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
engine::api::TripParameters parameters;
|
engine::api::TripParameters parameters;
|
||||||
|
Loading…
Reference in New Issue
Block a user