Restrict whiskers parameters to regular characters.

This commit is contained in:
chriseth 2019-06-19 18:46:16 +02:00
parent ee89a0353e
commit fc6f47e453
3 changed files with 38 additions and 5 deletions

View File

@ -37,6 +37,7 @@ Whiskers::Whiskers(string _template):
Whiskers& Whiskers::operator()(string _parameter, string _value) Whiskers& Whiskers::operator()(string _parameter, string _value)
{ {
checkParameterValid(_parameter);
checkParameterUnknown(_parameter); checkParameterUnknown(_parameter);
m_parameters[move(_parameter)] = move(_value); m_parameters[move(_parameter)] = move(_value);
return *this; return *this;
@ -44,6 +45,7 @@ Whiskers& Whiskers::operator()(string _parameter, string _value)
Whiskers& Whiskers::operator()(string _parameter, bool _value) Whiskers& Whiskers::operator()(string _parameter, bool _value)
{ {
checkParameterValid(_parameter);
checkParameterUnknown(_parameter); checkParameterUnknown(_parameter);
m_conditions[move(_parameter)] = _value; m_conditions[move(_parameter)] = _value;
return *this; return *this;
@ -54,7 +56,11 @@ Whiskers& Whiskers::operator()(
vector<map<string, string>> _values vector<map<string, string>> _values
) )
{ {
checkParameterValid(_listParameter);
checkParameterUnknown(_listParameter); checkParameterUnknown(_listParameter);
for (auto const& element: _values)
for (auto const& val: element)
checkParameterValid(val.first);
m_listParameters[move(_listParameter)] = move(_values); m_listParameters[move(_listParameter)] = move(_values);
return *this; return *this;
} }
@ -64,7 +70,17 @@ string Whiskers::render() const
return replace(m_template, m_parameters, m_conditions, m_listParameters); return replace(m_template, m_parameters, m_conditions, m_listParameters);
} }
void Whiskers::checkParameterUnknown(string const& _parameter) void Whiskers::checkParameterValid(string const& _parameter) const
{
static boost::regex validParam("^" + paramRegex() + "$");
assertThrow(
boost::regex_match(_parameter, validParam),
WhiskersError,
"Parameter" + _parameter + " contains invalid characters."
);
}
void Whiskers::checkParameterUnknown(string const& _parameter) const
{ {
assertThrow( assertThrow(
!m_parameters.count(_parameter), !m_parameters.count(_parameter),
@ -91,7 +107,7 @@ string Whiskers::replace(
) )
{ {
using namespace boost; using namespace boost;
static regex listOrTag("<([^#/?!>]+)>|<#([^>]+)>(.*?)</\\2>|<\\?([^>]+)>(.*?)(<!\\4>(.*?))?</\\4>"); static regex listOrTag("<(" + paramRegex() + ")>|<#(" + paramRegex() + ")>(.*?)</\\2>|<\\?(" + paramRegex() + ")>(.*?)(<!\\4>(.*?))?</\\4>");
return regex_replace(_template, listOrTag, [&](match_results<string::const_iterator> _match) -> string return regex_replace(_template, listOrTag, [&](match_results<string::const_iterator> _match) -> string
{ {
string tagName(_match[1]); string tagName(_match[1]);

View File

@ -85,7 +85,8 @@ public:
std::string render() const; std::string render() const;
private: private:
void checkParameterUnknown(std::string const& _parameter); void checkParameterValid(std::string const& _parameter) const;
void checkParameterUnknown(std::string const& _parameter) const;
static std::string replace( static std::string replace(
std::string const& _template, std::string const& _template,
@ -94,6 +95,8 @@ private:
StringListMap const& _listParameters = StringListMap() StringListMap const& _listParameters = StringListMap()
); );
static std::string paramRegex() { return "[a-zA-Z0-9_$-]+"; }
/// Joins the two maps throwing an exception if two keys are equal. /// Joins the two maps throwing an exception if two keys are equal.
static StringMap joinMaps(StringMap const& _a, StringMap const& _b); static StringMap joinMaps(StringMap const& _a, StringMap const& _b);

View File

@ -116,11 +116,11 @@ BOOST_AUTO_TEST_CASE(conditional_plus_list)
BOOST_AUTO_TEST_CASE(complicated_replacement) BOOST_AUTO_TEST_CASE(complicated_replacement)
{ {
string templ = "a <b> x <complicated> \n <nes<ted>>."; string templ = "a <b> x <complicated> \n <nested>>.";
string result = Whiskers(templ) string result = Whiskers(templ)
("b", "BE") ("b", "BE")
("complicated", "CO<M>PL") ("complicated", "CO<M>PL")
("nes<ted", "NEST") ("nested", "NEST")
.render(); .render();
BOOST_CHECK_EQUAL(result, "a BE x CO<M>PL \n NEST>."); BOOST_CHECK_EQUAL(result, "a BE x CO<M>PL \n NEST>.");
} }
@ -180,6 +180,20 @@ BOOST_AUTO_TEST_CASE(parameter_collision)
BOOST_CHECK_THROW(m.render(), WhiskersError); BOOST_CHECK_THROW(m.render(), WhiskersError);
} }
BOOST_AUTO_TEST_CASE(invalid_param)
{
string templ = "a <b >";
Whiskers m(templ);
BOOST_CHECK_THROW(m("b ", "X"), WhiskersError);
}
BOOST_AUTO_TEST_CASE(invalid_param_rendered)
{
string templ = "a <b >";
Whiskers m(templ);
BOOST_CHECK_EQUAL(m.render(), templ);
}
BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE_END()
} }