From: Razvan Becheriu Date: Tue, 16 Mar 2021 13:11:34 +0000 (+0200) Subject: [#1680] added EvalContext convert functions X-Git-Tag: Kea-1.9.8~135 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=53258fa8852607474d887bd24e0382eb71fa8914;p=thirdparty%2Fkea.git [#1680] added EvalContext convert functions --- diff --git a/src/lib/eval/eval_context.cc b/src/lib/eval/eval_context.cc index 548ad15423..5830007e2a 100644 --- a/src/lib/eval/eval_context.cc +++ b/src/lib/eval/eval_context.cc @@ -25,8 +25,7 @@ EvalContext::EvalContext(const Option::Universe& option_universe, { } -EvalContext::~EvalContext() -{ +EvalContext::~EvalContext() { } bool @@ -35,8 +34,7 @@ EvalContext::acceptAll(const ClientClass&) { } bool -EvalContext::parseString(const std::string& str, ParserType type) -{ +EvalContext::parseString(const std::string& str, ParserType type) { file_ = ""; string_ = str; scanStringBegin(type); @@ -54,21 +52,18 @@ EvalContext::parseString(const std::string& str, ParserType type) } void -EvalContext::error(const isc::eval::location& loc, const std::string& what) -{ +EvalContext::error(const isc::eval::location& loc, const std::string& what) { isc_throw(EvalParseError, loc << ": " << what); } void -EvalContext::error (const std::string& what) -{ +EvalContext::error (const std::string& what) { isc_throw(EvalParseError, what); } uint16_t EvalContext::convertOptionCode(const std::string& option_code, - const isc::eval::location& loc) -{ + const isc::eval::location& loc) { int n = 0; try { n = boost::lexical_cast(option_code); @@ -92,8 +87,7 @@ EvalContext::convertOptionCode(const std::string& option_code, uint16_t EvalContext::convertOptionName(const std::string& option_name, - const isc::eval::location& loc) -{ + const isc::eval::location& loc) { const std::string global_space = (option_universe_ == Option::V4) ? DHCP4_OPTION_SPACE : DHCP6_OPTION_SPACE; @@ -116,8 +110,7 @@ EvalContext::convertOptionName(const std::string& option_name, int8_t EvalContext::convertNestLevelNumber(const std::string& nest_level, - const isc::eval::location& loc) -{ + const isc::eval::location& loc) { int8_t n = convertInt8(nest_level, loc); if (option_universe_ == Option::V6) { if ((n < - HOP_COUNT_LIMIT) || (n >= HOP_COUNT_LIMIT)) { @@ -133,11 +126,10 @@ EvalContext::convertNestLevelNumber(const std::string& nest_level, uint8_t EvalContext::convertUint8(const std::string& number, - const isc::eval::location& loc) -{ - int n = 0; + const isc::eval::location& loc) { + int32_t n = 0; try { - n = boost::lexical_cast(number); + n = boost::lexical_cast(number); } catch (const boost::bad_lexical_cast &) { error(loc, "Invalid integer value in " + number); } @@ -151,34 +143,67 @@ EvalContext::convertUint8(const std::string& number, int8_t EvalContext::convertInt8(const std::string& number, - const isc::eval::location& loc) -{ - int n = 0; + const isc::eval::location& loc) { + int32_t n = 0; try { - n = boost::lexical_cast(number); + n = boost::lexical_cast(number); } catch (const boost::bad_lexical_cast &) { error(loc, "Invalid integer value in " + number); } if (n < std::numeric_limits::min() || n > std::numeric_limits::max()) { error(loc, "Invalid value in " - + number + ". Allowed range: 0..255"); + + number + ". Allowed range: -128..127"); } - return (static_cast(n)); + return (static_cast(n)); +} + +uint16_t +EvalContext::convertUint16(const std::string& number, + const isc::eval::location& loc) { + int64_t n = 0; + try { + n = boost::lexical_cast(number); + } catch (const boost::bad_lexical_cast &) { + error(loc, "Invalid value in " + number); + } + if (n < 0 || n > std::numeric_limits::max()) { + error(loc, "Invalid value in " + + number + ". Allowed range: 0..65535"); + } + + return (static_cast(n)); +} + +int16_t +EvalContext::convertInt16(const std::string& number, + const isc::eval::location& loc) { + uint64_t n = 0; + try { + n = boost::lexical_cast(number); + } catch (const boost::bad_lexical_cast &) { + error(loc, "Invalid value in " + number); + } + if (n > std::numeric_limits::max() || + n < std::numeric_limits::max()) { + error(loc, "Invalid value in " + + number + ". Allowed range: -32768..32767"); + } + + return (static_cast(n)); } uint32_t EvalContext::convertUint32(const std::string& number, - const isc::eval::location& loc) -{ - uint64_t n = 0; + const isc::eval::location& loc) { + int64_t n = 0; try { - n = boost::lexical_cast(number); + n = boost::lexical_cast(number); } catch (const boost::bad_lexical_cast &) { error(loc, "Invalid value in " + number); } - if (n > std::numeric_limits::max()) { + if (n < 0 || n > std::numeric_limits::max()) { error(loc, "Invalid value in " + number + ". Allowed range: 0..4294967295"); } @@ -186,6 +211,24 @@ EvalContext::convertUint32(const std::string& number, return (static_cast(n)); } +int32_t +EvalContext::convertInt32(const std::string& number, + const isc::eval::location& loc) { + int64_t n = 0; + try { + n = boost::lexical_cast(number); + } catch (const boost::bad_lexical_cast &) { + error(loc, "Invalid value in " + number); + } + if (n > std::numeric_limits::max() || + n < std::numeric_limits::max()) { + error(loc, "Invalid value in " + + number + ". Allowed range: -2147483648..2147483647"); + } + + return (static_cast(n)); +} + std::string EvalContext::fromUint32(const uint32_t integer) { std::string tmp(4, 0); @@ -197,13 +240,21 @@ EvalContext::fromUint32(const uint32_t integer) { return (tmp); } +std::string +EvalContext::fromUint16(const uint16_t integer) { + std::string tmp(2, 0); + tmp[0] = (integer >> 8) & 0xff; + tmp[1] = integer & 0xff; + + return (tmp); +} + bool EvalContext::isClientClassDefined(const ClientClass& client_class) { return (check_defined_(client_class)); } void -EvalContext::fatal (const std::string& what) -{ +EvalContext::fatal(const std::string& what) { isc_throw(Unexpected, what); } diff --git a/src/lib/eval/eval_context.h b/src/lib/eval/eval_context.h index bd47ae791e..2895e90dff 100644 --- a/src/lib/eval/eval_context.h +++ b/src/lib/eval/eval_context.h @@ -31,8 +31,7 @@ public: /// @brief Evaluation context, an interface to the expression evaluation. -class EvalContext -{ +class EvalContext { public: /// @brief Specifies what type of expression the parser is expected to see @@ -136,6 +135,35 @@ public: static uint32_t convertUint32(const std::string& number, const isc::eval::location& loc); + /// @brief Attempts to convert string to signed 32bit integer + /// + /// @param number string to be converted + /// @param loc the location of the token + /// @return the integer value + /// @throw EvalParseError if conversion fails or the value is out of range. + static int32_t convertInt32(const std::string& number, + const isc::eval::location& loc); + + /// @brief Attempts to convert string to unsigned 16bit integer + /// + /// For reverse conversion, see @ref fromUint16 + /// + /// @param number string to be converted + /// @param loc the location of the token + /// @return the integer value + /// @throw EvalParseError if conversion fails or the value is out of range. + static uint16_t convertUint16(const std::string& number, + const isc::eval::location& loc); + + /// @brief Attempts to convert string to signed 16bit integer + /// + /// @param number string to be converted + /// @param loc the location of the token + /// @return the integer value + /// @throw EvalParseError if conversion fails or the value is out of range. + static int16_t convertInt16(const std::string& number, + const isc::eval::location& loc); + /// @brief Attempts to convert string to unsigned 8bit integer /// /// @param number string to be converted @@ -164,7 +192,7 @@ public: int8_t convertNestLevelNumber(const std::string& nest_level, const isc::eval::location& loc); - /// @brief Converts integer to string representation + /// @brief Converts unsigned 32bit integer to string representation /// /// The integer is coded as a 4 byte long string in network order, e.g. /// 6 is represented as 00000006. For reverse conversion, see @@ -174,6 +202,16 @@ public: /// @return 4 byte long string that encodes the value. static std::string fromUint32(const uint32_t integer); + /// @brief Converts unsigned 16bit integer to string representation + /// + /// The integer is coded as a 2 byte long string in network order, e.g. + /// 6 is represented as 0006. For reverse conversion, see + /// @ref convertUint16. + /// + /// @param integer value to be converted + /// @return 2 byte long string that encodes the value. + static std::string fromUint16(const uint16_t integer); + /// @brief Returns the universe (v4 or v6) /// /// @return universe @@ -205,7 +243,7 @@ public: }; -}; // end of isc::eval namespace -}; // end of isc namespace +} // end of isc::eval namespace +} // end of isc namespace #endif diff --git a/src/lib/eval/token.cc b/src/lib/eval/token.cc index fded03d7cb..760d460038 100644 --- a/src/lib/eval/token.cc +++ b/src/lib/eval/token.cc @@ -171,7 +171,8 @@ TokenInt16ToText::evaluate(Pkt& /*pkt*/, ValueStack& values) { stringstream tmp; uint16_t value = *(reinterpret_cast(const_cast(op.data()))); - tmp << static_cast(ntohs(value)); + std::string data = EvalContext::fromUint16(value); + tmp << *(reinterpret_cast(const_cast(data.data()))); op = tmp.str(); values.push(op); @@ -195,7 +196,8 @@ TokenInt32ToText::evaluate(Pkt& /*pkt*/, ValueStack& values) { stringstream tmp; uint32_t value = *(reinterpret_cast(const_cast(op.data()))); - tmp << static_cast(ntohl(value)); + std::string data = EvalContext::fromUint32(value); + tmp << *(reinterpret_cast(const_cast(data.data()))); op = tmp.str(); values.push(op); @@ -242,7 +244,8 @@ TokenUInt16ToText::evaluate(Pkt& /*pkt*/, ValueStack& values) { stringstream tmp; uint16_t value = *(reinterpret_cast(const_cast(op.data()))); - tmp << ntohs(value); + std::string data = EvalContext::fromUint16(value); + tmp << *(reinterpret_cast(const_cast(data.data()))); op = tmp.str(); values.push(op); @@ -266,7 +269,8 @@ TokenUInt32ToText::evaluate(Pkt& /*pkt*/, ValueStack& values) { stringstream tmp; uint32_t value = *(reinterpret_cast(const_cast(op.data()))); - tmp << ntohl(value); + std::string data = EvalContext::fromUint32(value); + tmp << *(reinterpret_cast(const_cast(data.data()))); op = tmp.str(); values.push(op);