Commit 29282dfa authored by Francis Dupont's avatar Francis Dupont
Browse files

[4088fd] Assume the parser produces only well typed expressions

parent 2760bbdf
......@@ -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.
......@@ -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_));
// verify results
ASSERT_EQ(1, values_.size());
EXPECT_EQ(result_string, values_.top());
// remove result
values_.pop();
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());
// 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
......
......@@ -121,19 +121,21 @@ TokenSubstring::evaluate(const Pkt& /*pkt*/, ValueStack& values) {
int length;
try {
start_pos = boost::lexical_cast<int>(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<int>(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();
......
......@@ -38,7 +38,7 @@ typedef std::vector<TokenPtr> Expression;
/// Evaluated values are stored as a stack of strings
typedef std::stack<std::string> 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
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment