2
0
mirror of https://gitlab.isc.org/isc-projects/kea synced 2025-08-30 05:27:55 +00:00

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

This commit is contained in:
Francis Dupont 2015-11-06 14:08:09 +01:00
parent 2760bbdf57
commit 29282dfa0f
4 changed files with 41 additions and 27 deletions

View File

@ -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.

View File

@ -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

View File

@ -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();

View File

@ -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