summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrii Kalinich (GitHub) <AKalinich@luxoft.com>2021-08-25 09:47:45 -0400
committerGitHub <noreply@github.com>2021-08-25 09:47:45 -0400
commite75bd4f3131b63e7e7f805bc36eb70c758c37640 (patch)
tree3c2c54b09110d69858cd8a784105109c71019888
parent90879643717a1f8fef5061345e5e9b279329619f (diff)
downloadsdl_core-e75bd4f3131b63e7e7f805bc36eb70c758c37640.tar.gz
Fix SDL crash on validation of numeric schemas with type overflow (#3750)
* Added handling of cases with type overflow * Update generator logic and schema validation * Add validation info Co-authored-by: Jacob Keeler <jacob.keeler@livioradio.com>
-rw-r--r--src/components/smart_objects/include/smart_objects/number_schema_item.h23
-rw-r--r--src/components/smart_objects/src/number_schema_item.cc5
-rw-r--r--src/components/utils/include/utils/convert_utils.h14
-rwxr-xr-xtools/InterfaceGenerator/generator/generators/SmartFactoryBase.py23
4 files changed, 45 insertions, 20 deletions
diff --git a/src/components/smart_objects/include/smart_objects/number_schema_item.h b/src/components/smart_objects/include/smart_objects/number_schema_item.h
index 25b7684829..5fa9597db7 100644
--- a/src/components/smart_objects/include/smart_objects/number_schema_item.h
+++ b/src/components/smart_objects/include/smart_objects/number_schema_item.h
@@ -135,6 +135,7 @@ bool TNumberSchemaItem<NumberType>::isValidNumberType(SmartType type) {
typeid(int32_t),
typeid(uint32_t),
typeid(int64_t),
+ typeid(uint64_t),
typeid(double))) {
return true;
}
@@ -157,11 +158,26 @@ errors::eType TNumberSchemaItem<NumberType>::validate(
report->set_validation_info(validation_info);
return errors::INVALID_VALUE;
}
+
NumberType value(0);
if (typeid(int32_t) == typeid(value)) {
- value = utils::SafeStaticCast<int64_t, int32_t>(Object.asInt());
+ if (Object.asInt() < std::numeric_limits<int32_t>::min() ||
+ Object.asInt() > std::numeric_limits<int32_t>::max()) {
+ const std::string validation_info =
+ "Value " + Object.asString() + " out of int32 range";
+ report->set_validation_info(validation_info);
+ return errors::OUT_OF_RANGE;
+ }
+ value = Object.asInt();
} else if (typeid(uint32_t) == typeid(value)) {
- value = utils::SafeStaticCast<uint64_t, uint32_t>(Object.asUInt());
+ if (Object.asInt() < std::numeric_limits<uint32_t>::min() ||
+ Object.asInt() > std::numeric_limits<uint32_t>::max()) {
+ const std::string validation_info =
+ "Value " + Object.asString() + " out of uint32 range";
+ report->set_validation_info(validation_info);
+ return errors::OUT_OF_RANGE;
+ }
+ value = Object.asUInt();
} else if (typeid(double) == typeid(value)) {
value = Object.asDouble();
} else if (typeid(int64_t) == typeid(value)) {
@@ -231,6 +247,9 @@ template <>
SmartType TNumberSchemaItem<int64_t>::getSmartType() const;
template <>
+SmartType TNumberSchemaItem<uint64_t>::getSmartType() const;
+
+template <>
SmartType TNumberSchemaItem<double>::getSmartType() const;
} // namespace ns_smart_objects
diff --git a/src/components/smart_objects/src/number_schema_item.cc b/src/components/smart_objects/src/number_schema_item.cc
index c383f6ecca..1874ff30a0 100644
--- a/src/components/smart_objects/src/number_schema_item.cc
+++ b/src/components/smart_objects/src/number_schema_item.cc
@@ -50,6 +50,11 @@ SmartType TNumberSchemaItem<int64_t>::getSmartType() const {
}
template <>
+SmartType TNumberSchemaItem<uint64_t>::getSmartType() const {
+ return SmartType_UInteger;
+}
+
+template <>
SmartType TNumberSchemaItem<double>::getSmartType() const {
return SmartType_Double;
}
diff --git a/src/components/utils/include/utils/convert_utils.h b/src/components/utils/include/utils/convert_utils.h
index ba23b620dc..e51cf8cd57 100644
--- a/src/components/utils/include/utils/convert_utils.h
+++ b/src/components/utils/include/utils/convert_utils.h
@@ -70,20 +70,6 @@ unsigned long long int ConvertUInt64ToLongLongUInt(const uint64_t value);
uint64_t ConvertLongLongUIntToUInt64(const unsigned long long int value);
/**
- * @brief Convert one number value to another type value
- * @param value to be converted
- * @return conversion result
- */
-template <typename InputType, typename OutputType>
-OutputType SafeStaticCast(const InputType value) {
- DCHECK_OR_RETURN(value >= std::numeric_limits<OutputType>::min(),
- std::numeric_limits<OutputType>::min());
- DCHECK_OR_RETURN(value <= std::numeric_limits<OutputType>::max(),
- std::numeric_limits<OutputType>::max());
- return static_cast<OutputType>(value);
-}
-
-/**
* @brief Convert binary data to a string value
* @param data raw binary data
* @param data_size string length. Required to check whether the data is a
diff --git a/tools/InterfaceGenerator/generator/generators/SmartFactoryBase.py b/tools/InterfaceGenerator/generator/generators/SmartFactoryBase.py
index 69e8d71428..dffaa6c1b5 100755
--- a/tools/InterfaceGenerator/generator/generators/SmartFactoryBase.py
+++ b/tools/InterfaceGenerator/generator/generators/SmartFactoryBase.py
@@ -840,22 +840,37 @@ class CodeGenerator(object):
[[u"bool", None if param.default_value is None
else u"true" if param.default_value is True else u"false"]]))
elif type(param) is Integer:
- if not param.max_value or param.max_value and param.max_value < 2 ** 31:
+ if param.min_value is not None and param.min_value >= 0:
+ if param.max_value is None or param.max_value >= 2 ** 32:
+ code = self._impl_code_integer_item_template.substitute(
+ type=u"uint64_t",
+ params=self._gen_schema_item_param_values(
+ [[u"uint64_t", param.min_value],
+ [u"uint64_t", param.max_value],
+ [u"uint64_t", param.default_value]]))
+ else:
+ code = self._impl_code_integer_item_template.substitute(
+ type=u"uint32_t",
+ params=self._gen_schema_item_param_values(
+ [[u"uint32_t", param.min_value],
+ [u"uint32_t", param.max_value],
+ [u"uint32_t", param.default_value]]))
+ elif (param.min_value is not None and param.min_value >= -(2 ** 31)) and (param.max_value is not None and param.max_value < 2 ** 31):
code = self._impl_code_integer_item_template.substitute(
type=u"int32_t",
params=self._gen_schema_item_param_values(
[[u"int32_t", param.min_value],
[u"int32_t", param.max_value],
[u"int32_t", param.default_value]]))
- elif param.max_value < 2 ** 63:
+ elif (param.min_value is None or param.min_value >= -(2 ** 63)) and (param.max_value is None or param.max_value < 2 ** 63):
code = self._impl_code_integer_item_template.substitute(
type=u"int64_t",
params=self._gen_schema_item_param_values(
[[u"int64_t", param.min_value],
- [u"int64_t", str(param.max_value) + u"LL"],
+ [u"int64_t", param.max_value],
[u"int64_t", param.default_value]]))
else:
- raise GenerateError("Parameter value too large: " + str(param.max_value))
+ raise GenerateError("Parameter value too large/small: " + str(param.min_value) + "/" + str(param.max_value))
elif type(param) is Float:
code = self._impl_code_integer_item_template.substitute(
type=u"double",