mirror of
https://github.com/espressif/openthread.git
synced 2026-06-06 05:24:51 +00:00
[dns] add MatchesKey() to Dns::TxtEntry (#12579)
This commit adds `MatchesKey()` method to `Dns::TxtEntry` class to check if the entry's key matches a given key string using a case-insensitive string comparison. The new method properly handles the case where the entry's key is `nullptr` (which can happen when the key is longer than the recommended max length). It simplifies the TXT entry parsing logic in `BorderAgent` and `Trel::PeerDiscoverer`. The unit tests for `Dns::TxtEntry` are also updated to verify the new method.
This commit is contained in:
committed by
GitHub
parent
be4ce643ec
commit
d0237f5e91
@@ -303,28 +303,21 @@ Error TxtData::Info::ParseFrom(const uint8_t *aTxtData, uint16_t aTxtDataLength)
|
||||
|
||||
void TxtData::Info::ProcessTxtEntry(const Dns::TxtEntry &aEntry)
|
||||
{
|
||||
if (aEntry.mKey == nullptr)
|
||||
{
|
||||
// If the TXT data happens to have entries with key longer
|
||||
// than `kMaxIterKeyLength`, `mKey` would be `nullptr` and full
|
||||
// entry would be placed in `mValue`. We skip over such
|
||||
// entries.
|
||||
}
|
||||
else if (StringMatch(aEntry.mKey, Key::kRecordVersion))
|
||||
if (aEntry.MatchesKey(Key::kRecordVersion))
|
||||
{
|
||||
ReadStringValue(aEntry, mRecordVersion);
|
||||
mHasRecordVersion = true;
|
||||
}
|
||||
else if (StringMatch(aEntry.mKey, Key::kAgentId))
|
||||
else if (aEntry.MatchesKey(Key::kAgentId))
|
||||
{
|
||||
mHasAgentId = ReadValue(aEntry, mAgentId);
|
||||
}
|
||||
else if (StringMatch(aEntry.mKey, Key::kThreadVersion))
|
||||
else if (aEntry.MatchesKey(Key::kThreadVersion))
|
||||
{
|
||||
ReadStringValue(aEntry, mThreadVersion);
|
||||
mHasThreadVersion = true;
|
||||
}
|
||||
else if (StringMatch(aEntry.mKey, Key::kStateBitmap))
|
||||
else if (aEntry.MatchesKey(Key::kStateBitmap))
|
||||
{
|
||||
uint32_t bitmap;
|
||||
|
||||
@@ -334,16 +327,16 @@ void TxtData::Info::ProcessTxtEntry(const Dns::TxtEntry &aEntry)
|
||||
mHasStateBitmap = true;
|
||||
}
|
||||
}
|
||||
else if (StringMatch(aEntry.mKey, Key::kNetworkName))
|
||||
else if (aEntry.MatchesKey(Key::kNetworkName))
|
||||
{
|
||||
ReadStringValue(aEntry, mNetworkName.m8);
|
||||
mHasNetworkName = true;
|
||||
}
|
||||
else if (StringMatch(aEntry.mKey, Key::kExtendedPanId))
|
||||
else if (aEntry.MatchesKey(Key::kExtendedPanId))
|
||||
{
|
||||
mHasExtendedPanId = ReadValue(aEntry, mExtendedPanId);
|
||||
}
|
||||
else if (StringMatch(aEntry.mKey, Key::kActiveTimestamp))
|
||||
else if (aEntry.MatchesKey(Key::kActiveTimestamp))
|
||||
{
|
||||
Timestamp timestamp;
|
||||
|
||||
@@ -353,37 +346,37 @@ void TxtData::Info::ProcessTxtEntry(const Dns::TxtEntry &aEntry)
|
||||
mHasActiveTimestamp = true;
|
||||
}
|
||||
}
|
||||
else if (StringMatch(aEntry.mKey, Key::kPartitionId))
|
||||
else if (aEntry.MatchesKey(Key::kPartitionId))
|
||||
{
|
||||
mHasPartitionId = ReadBigEndianUintValue(aEntry, mPartitionId);
|
||||
}
|
||||
else if (StringMatch(aEntry.mKey, Key::kDomainName))
|
||||
else if (aEntry.MatchesKey(Key::kDomainName))
|
||||
{
|
||||
ReadStringValue(aEntry, mDomainName.m8);
|
||||
mHasDomainName = true;
|
||||
}
|
||||
else if (StringMatch(aEntry.mKey, Key::kBbrSeqNum))
|
||||
else if (aEntry.MatchesKey(Key::kBbrSeqNum))
|
||||
{
|
||||
mHasBbrSeqNum = ReadBigEndianUintValue(aEntry, mBbrSeqNum);
|
||||
}
|
||||
else if (StringMatch(aEntry.mKey, Key::kBbrPort))
|
||||
else if (aEntry.MatchesKey(Key::kBbrPort))
|
||||
{
|
||||
mHasBbrPort = ReadBigEndianUintValue(aEntry, mBbrPort);
|
||||
}
|
||||
else if (StringMatch(aEntry.mKey, Key::kOmrPrefix))
|
||||
else if (aEntry.MatchesKey(Key::kOmrPrefix))
|
||||
{
|
||||
mHasOmrPrefix = ReadOmrPrefix(aEntry, AsCoreType(&mOmrPrefix));
|
||||
}
|
||||
else if (StringMatch(aEntry.mKey, Key::kExtAddress))
|
||||
else if (aEntry.MatchesKey(Key::kExtAddress))
|
||||
{
|
||||
mHasExtAddress = ReadValue(aEntry, mExtAddress);
|
||||
}
|
||||
else if (StringMatch(aEntry.mKey, Key::kVendorName))
|
||||
else if (aEntry.MatchesKey(Key::kVendorName))
|
||||
{
|
||||
ReadStringValue(aEntry, mVendorName);
|
||||
mHasVendorName = true;
|
||||
}
|
||||
else if (StringMatch(aEntry.mKey, Key::kModelName))
|
||||
else if (aEntry.MatchesKey(Key::kModelName))
|
||||
{
|
||||
ReadStringValue(aEntry, mModelName);
|
||||
mHasModelName = true;
|
||||
|
||||
@@ -1380,6 +1380,11 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
bool TxtEntry::MatchesKey(const char *aKey) const
|
||||
{
|
||||
return (mKey != nullptr) && StringMatch(mKey, aKey, kStringCaseInsensitiveMatch);
|
||||
}
|
||||
|
||||
Error TxtEntry::AppendTo(Message &aMessage) const
|
||||
{
|
||||
Appender appender(aMessage);
|
||||
|
||||
@@ -1223,6 +1223,16 @@ public:
|
||||
mValueLength = aValueLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether the entry's key (`mKey`) matches a given key string using a case-insensitive comparison.
|
||||
*
|
||||
* @param[in] aKey A pointer to a key string to compare with.
|
||||
*
|
||||
* @retval TRUE The entry's key matches the given @p aKey.
|
||||
* @retval FALSE The entry's key does not match or `mKey` is `nullptr`.
|
||||
*/
|
||||
bool MatchesKey(const char *aKey) const;
|
||||
|
||||
/**
|
||||
* Encodes and appends the `TxtEntry` to a message.
|
||||
*
|
||||
|
||||
@@ -750,23 +750,14 @@ Error PeerDiscoverer::TxtData::Decode(Info &aInfo)
|
||||
|
||||
while ((error = iterator.GetNextEntry(entry)) == kErrorNone)
|
||||
{
|
||||
// If the TXT data happens to have entries with key longer
|
||||
// than `kMaxIterKeyLength`, `mKey` would be `nullptr` and full
|
||||
// entry would be placed in `mValue`. We skip over such
|
||||
// entries.
|
||||
if (entry.mKey == nullptr)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (StringMatch(entry.mKey, kExtAddressKey))
|
||||
if (entry.MatchesKey(kExtAddressKey))
|
||||
{
|
||||
VerifyOrExit(!parsedExtAddress, error = kErrorParse);
|
||||
VerifyOrExit(entry.mValueLength >= sizeof(Mac::ExtAddress), error = kErrorParse);
|
||||
aInfo.mExtAddress.Set(entry.mValue);
|
||||
parsedExtAddress = true;
|
||||
}
|
||||
else if (StringMatch(entry.mKey, kExtPanIdKey))
|
||||
else if (entry.MatchesKey(kExtPanIdKey))
|
||||
{
|
||||
VerifyOrExit(!parsedExtPanId, error = kErrorParse);
|
||||
VerifyOrExit(entry.mValueLength >= sizeof(MeshCoP::ExtendedPanId), error = kErrorParse);
|
||||
|
||||
+12
-4
@@ -34,6 +34,7 @@
|
||||
#include "test_util.hpp"
|
||||
|
||||
#include "common/array.hpp"
|
||||
#include "common/string.hpp"
|
||||
#include "instance/instance.hpp"
|
||||
#include "net/dns_types.hpp"
|
||||
|
||||
@@ -1632,10 +1633,8 @@ void TestHeaderAndResourceRecords(void)
|
||||
|
||||
void TestDnsTxtEntry(void)
|
||||
{
|
||||
enum
|
||||
{
|
||||
kMaxTxtDataSize = 255,
|
||||
};
|
||||
static constexpr uint16_t kMaxTxtDataSize = 255;
|
||||
static constexpr uint16_t kMaxKeyStringSize = Dns::TxtEntry::kMaxIterKeyLength;
|
||||
|
||||
struct EncodedTxtData
|
||||
{
|
||||
@@ -1718,6 +1717,7 @@ void TestDnsTxtEntry(void)
|
||||
Dns::TxtEntry txtEntry;
|
||||
Dns::TxtEntry::Iterator iterator;
|
||||
MutableData<kWithUint16Length> data;
|
||||
char keyString[kMaxKeyStringSize];
|
||||
|
||||
printf("================================================================\n");
|
||||
printf("TestDnsTxtEntry()\n");
|
||||
@@ -1772,6 +1772,14 @@ void TestDnsTxtEntry(void)
|
||||
}
|
||||
|
||||
VerifyOrQuit(strcmp(txtEntry.mKey, expectedTxtEntry.mKey) == 0);
|
||||
|
||||
SuccessOrQuit(StringCopy(keyString, expectedTxtEntry.mKey));
|
||||
VerifyOrQuit(txtEntry.MatchesKey(keyString));
|
||||
StringConvertToLowercase(keyString);
|
||||
VerifyOrQuit(txtEntry.MatchesKey(keyString));
|
||||
StringConvertToUppercase(keyString);
|
||||
VerifyOrQuit(txtEntry.MatchesKey(keyString));
|
||||
|
||||
VerifyOrQuit(txtEntry.mValueLength == expectedTxtEntry.mValueLength);
|
||||
|
||||
if (txtEntry.mValueLength != 0)
|
||||
|
||||
Reference in New Issue
Block a user