diff --git a/libdevcore/Whiskers.cpp b/libdevcore/Whiskers.cpp index 8a20f2cd7..c48c8d6f1 100644 --- a/libdevcore/Whiskers.cpp +++ b/libdevcore/Whiskers.cpp @@ -37,6 +37,7 @@ Whiskers::Whiskers(string _template): Whiskers& Whiskers::operator()(string _parameter, string _value) { + checkParameterValid(_parameter); checkParameterUnknown(_parameter); m_parameters[move(_parameter)] = move(_value); return *this; @@ -44,6 +45,7 @@ Whiskers& Whiskers::operator()(string _parameter, string _value) Whiskers& Whiskers::operator()(string _parameter, bool _value) { + checkParameterValid(_parameter); checkParameterUnknown(_parameter); m_conditions[move(_parameter)] = _value; return *this; @@ -54,7 +56,11 @@ Whiskers& Whiskers::operator()( vector> _values ) { + checkParameterValid(_listParameter); checkParameterUnknown(_listParameter); + for (auto const& element: _values) + for (auto const& val: element) + checkParameterValid(val.first); m_listParameters[move(_listParameter)] = move(_values); return *this; } @@ -64,7 +70,17 @@ string Whiskers::render() const 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( !m_parameters.count(_parameter), @@ -91,7 +107,7 @@ string Whiskers::replace( ) { using namespace boost; - static regex listOrTag("<([^#/?!>]+)>|<#([^>]+)>(.*?)|<\\?([^>]+)>(.*?)((.*?))?"); + static regex listOrTag("<(" + paramRegex() + ")>|<#(" + paramRegex() + ")>(.*?)|<\\?(" + paramRegex() + ")>(.*?)((.*?))?"); return regex_replace(_template, listOrTag, [&](match_results _match) -> string { string tagName(_match[1]); diff --git a/libdevcore/Whiskers.h b/libdevcore/Whiskers.h index 7944358a0..ebe17b51c 100644 --- a/libdevcore/Whiskers.h +++ b/libdevcore/Whiskers.h @@ -85,7 +85,8 @@ public: std::string render() const; 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( std::string const& _template, @@ -94,6 +95,8 @@ private: 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. static StringMap joinMaps(StringMap const& _a, StringMap const& _b); diff --git a/test/libdevcore/Whiskers.cpp b/test/libdevcore/Whiskers.cpp index 8a785774e..924f2efd0 100644 --- a/test/libdevcore/Whiskers.cpp +++ b/test/libdevcore/Whiskers.cpp @@ -116,11 +116,11 @@ BOOST_AUTO_TEST_CASE(conditional_plus_list) BOOST_AUTO_TEST_CASE(complicated_replacement) { - string templ = "a x \n >."; + string templ = "a x \n >."; string result = Whiskers(templ) ("b", "BE") ("complicated", "COPL") - ("nesPL \n NEST>."); } @@ -180,6 +180,20 @@ BOOST_AUTO_TEST_CASE(parameter_collision) BOOST_CHECK_THROW(m.render(), WhiskersError); } +BOOST_AUTO_TEST_CASE(invalid_param) +{ + string templ = "a "; + Whiskers m(templ); + BOOST_CHECK_THROW(m("b ", "X"), WhiskersError); +} + +BOOST_AUTO_TEST_CASE(invalid_param_rendered) +{ + string templ = "a "; + Whiskers m(templ); + BOOST_CHECK_EQUAL(m.render(), templ); +} + BOOST_AUTO_TEST_SUITE_END() }