mirror of
https://github.com/espressif/openthread.git
synced 2026-08-04 09:57:47 +00:00
[joiner] enhance string TLV input validation (#12245)
This commit introduces a new generic method `Tlv::ValidateStringValue()` to provide a unified way of validating string values intended for use in string-valued TLVs. This new method checks that a given C string is a valid UTF-8 string and that its length does not exceed the maximum length defined by the `StringTlvType`. The `Joiner::Start()` method is updated to use this new validation method, which simplifies the code by replacing several explicit and repetitive checks. This improves code clarity and maintainability by centralizing the string validation logic. This commit also adds missing validation for `aVendorModel` in `Joiner::Start()`
This commit is contained in:
@@ -257,6 +257,19 @@ Error Tlv::AppendStringTlv(Message &aMessage, uint8_t aType, uint8_t aMaxStringL
|
||||
return AppendTlv(aMessage, aType, aValue, static_cast<uint8_t>(length));
|
||||
}
|
||||
|
||||
Error Tlv::ValidateStringTlvValue(uint8_t aMaxStringLength, const char *aStringValue)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
|
||||
VerifyOrExit(aStringValue != nullptr);
|
||||
|
||||
VerifyOrExit(StringLength(aStringValue, aMaxStringLength + 1) <= aMaxStringLength, error = kErrorInvalidArgs);
|
||||
VerifyOrExit(IsValidUtf8String(aStringValue), error = kErrorInvalidArgs);
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
template <typename UintType> Error Tlv::AppendUintTlv(Message &aMessage, uint8_t aType, UintType aValue)
|
||||
{
|
||||
UintType value = BigEndian::HostSwap<UintType>(aValue);
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
#include "common/const_cast.hpp"
|
||||
#include "common/encoding.hpp"
|
||||
#include "common/error.hpp"
|
||||
#include "common/numeric_limits.hpp"
|
||||
#include "common/offset_range.hpp"
|
||||
#include "common/type_traits.hpp"
|
||||
|
||||
@@ -633,6 +634,27 @@ public:
|
||||
return AppendStringTlv(aMessage, StringTlvType::kType, StringTlvType::kMaxStringLength, aValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates a given string value for a simple TLV with a UTF-8 string value.
|
||||
*
|
||||
* The @p aValue can be `nullptr` in which case it is treated as an empty string.
|
||||
*
|
||||
* @tparam StringTlvType The simple TLV type for which to validate the value (must be a sub-class of
|
||||
* `StringTlvInfo`).
|
||||
*
|
||||
* @param[in] aValue A pointer to a C string to validate.
|
||||
*
|
||||
* @retval kErrorNone The string value is valid for the given `StringTlvType`.
|
||||
* @retval kErrorInvalidArgs The string is not a valid UTF-8 string or its length is longer than the max allowed
|
||||
* length specified by `StringTlvType::kMaxStringLength`.
|
||||
*/
|
||||
template <typename StringTlvType> static Error ValidateStringValue(const char *aValue)
|
||||
{
|
||||
static_assert(StringTlvType::kMaxStringLength < NumericLimits<uint8_t>::kMax, "String TLV length is invalid");
|
||||
|
||||
return ValidateStringTlvValue(StringTlvType::kMaxStringLength, aValue);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------
|
||||
// Static methods for finding TLVs within a sequence of TLVs.
|
||||
|
||||
@@ -699,6 +721,7 @@ private:
|
||||
static Error ReadStringTlv(const Message &aMessage, uint16_t aOffset, uint8_t aMaxStringLength, char *aValue);
|
||||
static Error FindStringTlv(const Message &aMessage, uint8_t aType, uint8_t aMaxStringLength, char *aValue);
|
||||
static Error AppendStringTlv(Message &aMessage, uint8_t aType, uint8_t aMaxStringLength, const char *aValue);
|
||||
static Error ValidateStringTlvValue(uint8_t aMaxStringLength, const char *aStringValue);
|
||||
template <typename UintType> static Error ReadUintTlv(const Message &aMessage, uint16_t aOffset, UintType &aValue);
|
||||
template <typename UintType> static Error FindUintTlv(const Message &aMessage, uint8_t aType, UintType &aValue);
|
||||
template <typename UintType> static Error AppendUintTlv(Message &aMessage, uint8_t aType, UintType aValue);
|
||||
|
||||
@@ -120,9 +120,10 @@ Error Joiner::Start(const char *aPskd,
|
||||
|
||||
LogInfo("Joiner starting");
|
||||
|
||||
VerifyOrExit(aProvisioningUrl == nullptr || IsValidUtf8String(aProvisioningUrl), error = kErrorInvalidArgs);
|
||||
VerifyOrExit(aVendorName == nullptr || IsValidUtf8String(aVendorName), error = kErrorInvalidArgs);
|
||||
VerifyOrExit(aVendorSwVersion == nullptr || IsValidUtf8String(aVendorSwVersion), error = kErrorInvalidArgs);
|
||||
SuccessOrExit(error = Tlv::ValidateStringValue<ProvisioningUrlTlv>(aProvisioningUrl));
|
||||
SuccessOrExit(error = Tlv::ValidateStringValue<VendorNameTlv>(aVendorName));
|
||||
SuccessOrExit(error = Tlv::ValidateStringValue<VendorModelTlv>(aVendorModel));
|
||||
SuccessOrExit(error = Tlv::ValidateStringValue<VendorSwVersionTlv>(aVendorSwVersion));
|
||||
|
||||
VerifyOrExit(mState == kStateIdle, error = kErrorBusy);
|
||||
VerifyOrExit(Get<ThreadNetif>().IsUp() && Get<Mle::Mle>().GetRole() == Mle::kRoleDisabled,
|
||||
|
||||
Reference in New Issue
Block a user