diff --git a/src/lib/eval/eval_messages.mes b/src/lib/eval/eval_messages.mes index 3d86f758b4..cca2b0e19e 100644 --- a/src/lib/eval/eval_messages.mes +++ b/src/lib/eval/eval_messages.mes @@ -18,8 +18,3 @@ $NAMESPACE isc::dhcp This debug message indicates that the expression has been evaluated to said value. This message is mostly useful during debugging of the client classification expressions. - -% EVAL_SUBSTRING_BAD_PARAM_CONVERSION starting %1, length %2 -This debug message indicates that the parameter for the starting postion -or length of the substring couldn't be converted to an integer. In this -case the substring routine returns an empty string. diff --git a/src/lib/eval/tests/token_unittest.cc b/src/lib/eval/tests/token_unittest.cc index 7f2d653f68..1fc8109d12 100644 --- a/src/lib/eval/tests/token_unittest.cc +++ b/src/lib/eval/tests/token_unittest.cc @@ -72,10 +72,12 @@ public: /// @param test_start The postion to start when getting a substring /// @param test_length The length of the substring to get /// @param result_string The expected result of the eval + /// @param should_throw The eval will throw void verifySubstringEval(const std::string& test_string, const std::string& test_start, const std::string& test_length, - const std::string& result_string) { + const std::string& result_string, + bool should_throw = false) { // create the token ASSERT_NO_THROW(t_.reset(new TokenSubstring())); @@ -86,14 +88,19 @@ public: values_.push(test_length); // evaluate the token - EXPECT_NO_THROW(t_->evaluate(*pkt4_, values_)); + if (should_throw) { + EXPECT_THROW(t_->evaluate(*pkt4_, values_), EvalTypeError); + ASSERT_EQ(0, values_.size()); + } else { + EXPECT_NO_THROW(t_->evaluate(*pkt4_, values_)); - // verify results - ASSERT_EQ(1, values_.size()); - EXPECT_EQ(result_string, values_.top()); + // verify results + ASSERT_EQ(1, values_.size()); + EXPECT_EQ(result_string, values_.top()); - // remove result - values_.pop(); + // remove result + values_.pop(); + } } /// @todo: Add more option types here @@ -443,13 +450,13 @@ TEST_F(TokenTest, substringStartingPosition) { // Check what happens if we use strings that aren't numbers for start or length // We should return the empty string TEST_F(TokenTest, substringBadParams) { - verifySubstringEval("foobar", "0ick", "all", ""); - verifySubstringEval("foobar", "ick0", "all", ""); - verifySubstringEval("foobar", "ick", "all", ""); - verifySubstringEval("foobar", "0", "ick", ""); - verifySubstringEval("foobar", "0", "0ick", ""); - verifySubstringEval("foobar", "0", "ick0", ""); - verifySubstringEval("foobar", "0", "allaboard", ""); + verifySubstringEval("foobar", "0ick", "all", "", true); + verifySubstringEval("foobar", "ick0", "all", "", true); + verifySubstringEval("foobar", "ick", "all", "", true); + verifySubstringEval("foobar", "0", "ick", "", true); + verifySubstringEval("foobar", "0", "0ick", "", true); + verifySubstringEval("foobar", "0", "ick0", "", true); + verifySubstringEval("foobar", "0", "allaboard", "", true); } // lastly check that we don't get anything if the string is empty or diff --git a/src/lib/eval/token.cc b/src/lib/eval/token.cc index ea01f11a76..e0a50bf7cd 100644 --- a/src/lib/eval/token.cc +++ b/src/lib/eval/token.cc @@ -121,19 +121,21 @@ TokenSubstring::evaluate(const Pkt& /*pkt*/, ValueStack& values) { int length; try { start_pos = boost::lexical_cast(start_str); + } catch (const boost::bad_lexical_cast&) { + isc_throw(EvalTypeError, "the parameter '" << start_str + << "' for the starting postion of the substring " + << "couldn't be converted to an integer."); + } + try { if (len_str == "all") { length = string_str.length(); } else { length = boost::lexical_cast(len_str); } } catch (const boost::bad_lexical_cast&) { - LOG_DEBUG(eval_logger, EVAL_DBG_TRACE, - EVAL_SUBSTRING_BAD_PARAM_CONVERSION) - .arg(start_str) - .arg(len_str); - - values.push(""); - return; + isc_throw(EvalTypeError, "the parameter '" << len_str + << "' for the length of the substring " + << "couldn't be converted to an integer."); } const int string_length = string_str.length(); diff --git a/src/lib/eval/token.h b/src/lib/eval/token.h index 4b264c2655..659d029b7c 100644 --- a/src/lib/eval/token.h +++ b/src/lib/eval/token.h @@ -38,7 +38,7 @@ typedef std::vector Expression; /// Evaluated values are stored as a stack of strings typedef std::stack ValueStack; -/// @brief EvalStackError is thrown when more or less parameters are on the +/// @brief EvalBadStack is thrown when more or less parameters are on the /// stack than expected. class EvalBadStack : public Exception { public: @@ -46,6 +46,14 @@ public: isc::Exception(file, line, what) { }; }; +/// @brief EvalTypeError is thrown when a value on the stack has a content +/// with an unexpected type. +class EvalTypeError : public Exception { +public: + EvalTypeError(const char* file, size_t line, const char* what) : + isc::Exception(file, line, what) { }; +}; + /// @brief Base class for all tokens /// /// It provides an interface for all tokens and storage for string representation @@ -241,6 +249,8 @@ public: /// - -1, -4 => "ooba" /// /// @throw EvalBadStack if there are less than 3 values on stack + /// @throw EvalTypeError if start is not a number or length a number or + /// the special value "all". /// /// @param pkt (unused) /// @param values - stack of values (3 arguments will be popped, 1 result