From 58a21b6146be4c473fa5163701ec172fa37c7cb1 Mon Sep 17 00:00:00 2001 From: Chirag Atal Date: Fri, 2 Dec 2022 16:31:29 +0530 Subject: [PATCH] esp_matter_attribute_utils: Fix crash for nullable attribute's assignment Removed the assert when the nullable attribute was being the actual null value. Handling this in the APIs now. --- .../esp_matter/esp_matter_attribute_utils.h | 45 ++++++++++++++++--- 1 file changed, 39 insertions(+), 6 deletions(-) diff --git a/components/esp_matter/esp_matter_attribute_utils.h b/components/esp_matter/esp_matter_attribute_utils.h index 49d15dfb5..188e24246 100644 --- a/components/esp_matter/esp_matter_attribute_utils.h +++ b/components/esp_matter/esp_matter_attribute_utils.h @@ -153,12 +153,38 @@ typedef struct esp_matter_attr_bounds { template class nullable { + +/** NOTE: GetNullValue is taken from src/app/util/attribute-storage-null-handling.h */ +private: + template ::value, int> = 0> + static constexpr T GetNullValue() + { + return std::numeric_limits::quiet_NaN(); + } + + template ::value, int> = 0> + static constexpr T GetNullValue() + { + return std::is_signed::value ? std::numeric_limits::min() : std::numeric_limits::max(); + } + + template ::value, int> = 0> + static constexpr T GetNullValue() + { + static_assert(!std::is_signed>::value, "Enums must be unsigned"); + return static_cast(std::numeric_limits>::max()); + } + public: nullable(T value) { - assert(!chip::app::NumericAttributeTraits::IsNullValue(value)); - val = value; + if (chip::app::NumericAttributeTraits::IsNullValue(value)) { + chip::app::NumericAttributeTraits::SetNull(val); + } else { + val = value; + } } + nullable() { chip::app::NumericAttributeTraits::SetNull(val); @@ -166,8 +192,12 @@ public: T value() { - assert(!is_null()); - return val; + if (is_null()) { + return GetNullValue(); + } else { + return val; + } + } T value_or(T ret) @@ -182,8 +212,11 @@ public: void operator=(T value) { - assert(!chip::app::NumericAttributeTraits::IsNullValue(value)); - this->val = value; + if (chip::app::NumericAttributeTraits::IsNullValue(value)) { + chip::app::NumericAttributeTraits::SetNull(this->val); + } else { + this->val = value; + } } void operator=(std::nullptr_t)