mgmt: check enum range during decoding
This commit also makes use of prependStringBlock and readString
functions in encode/decode routines.
refs #3974
Change-Id: I86a4f16ea6f50fffeff72c8b416878740e65ef2a
diff --git a/src/encoding/block-helpers.hpp b/src/encoding/block-helpers.hpp
index f1e14ff..5634ed6 100644
--- a/src/encoding/block-helpers.hpp
+++ b/src/encoding/block-helpers.hpp
@@ -63,6 +63,39 @@
uint64_t
readNonNegativeInteger(const Block& block);
+/** @brief Read a non-negative integer from a TLV element and cast to the specified type
+ * @tparam R result type, must be an integral type
+ * @param block the TLV element
+ * @throw tlv::Error block does not contain a valid non-negative integer or the number cannot be
+ * represented in R
+ */
+template<typename R>
+typename std::enable_if<std::is_integral<R>::value, R>::type
+readNonNegativeIntegerAs(const Block& block)
+{
+ uint64_t value = readNonNegativeInteger(block);
+ if (value > std::numeric_limits<R>::max()) {
+ BOOST_THROW_EXCEPTION(tlv::Error("Value in TLV element of type " + to_string(block.type()) +
+ " is too large"));
+ }
+ return static_cast<R>(value);
+}
+
+/** @brief Read a non-negative integer from a TLV element and cast to the specified type
+ * @tparam R result type, must be an enumeration type
+ * @param block the TLV element
+ * @throw tlv::Error block does not contain a valid non-negative integer or the number cannot be
+ * represented in R
+ * @warning If R is an unscoped enum type, it must have a fixed underlying type. Otherwise, this
+ * function may trigger unspecified behavior.
+ */
+template<typename R>
+typename std::enable_if<std::is_enum<R>::value, R>::type
+readNonNegativeIntegerAs(const Block& block)
+{
+ return static_cast<R>(readNonNegativeIntegerAs<typename std::underlying_type<R>::type>(block));
+}
+
/** @brief Prepend an empty TLV element
* @param encoder an EncodingBuffer or EncodingEstimator
* @param type TLV-TYPE number
@@ -255,6 +288,7 @@
using encoding::makeNonNegativeIntegerBlock;
using encoding::readNonNegativeInteger;
+using encoding::readNonNegativeIntegerAs;
using encoding::makeEmptyBlock;
using encoding::makeStringBlock;
using encoding::readString;