From 88950e15e1315e91c842076da5cf84e895b2b0ef Mon Sep 17 00:00:00 2001 From: whd <7058128+superwhd@users.noreply.github.com> Date: Sat, 28 Aug 2021 03:42:07 +0800 Subject: [PATCH] [dns] allow Data Length = 0 while reading a TXT record (#6961) RFC 6763 Section 6.1 states the following: An empty TXT record containing zero strings is not allowed [RFC1035]. DNS-SD implementations MUST NOT emit empty TXT records. DNS-SD clients MUST treat the following as equivalent: o A TXT record containing a single zero byte. (i.e., a single empty string.) o An empty (zero-length) TXT record. (This is not strictly legal, but should one be received, it should be interpreted as the same as a single empty string.) o No TXT record. (i.e., an NXDOMAIN or no-error-no-answer response.) This commit reflects the second requirement. --- src/core/net/dns_types.cpp | 6 +++--- src/core/net/dns_types.hpp | 7 ++++--- src/core/net/srp_server.cpp | 2 +- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/core/net/dns_types.cpp b/src/core/net/dns_types.cpp index 66c61308d..6ae316710 100644 --- a/src/core/net/dns_types.cpp +++ b/src/core/net/dns_types.cpp @@ -1084,7 +1084,7 @@ Error TxtRecord::ReadTxtData(const Message &aMessage, VerifyOrExit(GetLength() <= aTxtBufferSize, error = kErrorNoBufs); SuccessOrExit(error = aMessage.Read(aOffset, aTxtBuffer, GetLength())); - VerifyOrExit(VerifyTxtData(aTxtBuffer, GetLength()), error = kErrorParse); + VerifyOrExit(VerifyTxtData(aTxtBuffer, GetLength(), /* aAllowEmpty */ true), error = kErrorParse); aTxtBufferSize = GetLength(); aOffset += GetLength(); @@ -1092,13 +1092,13 @@ exit: return error; } -bool TxtRecord::VerifyTxtData(const uint8_t *aTxtData, uint16_t aTxtLength) +bool TxtRecord::VerifyTxtData(const uint8_t *aTxtData, uint16_t aTxtLength, bool aAllowEmpty) { bool valid = false; uint8_t curEntryLength = 0; // Per RFC 1035, TXT-DATA MUST have one or more s. - VerifyOrExit(aTxtLength > 0); + VerifyOrExit(aAllowEmpty || aTxtLength > 0); for (uint16_t i = 0; i < aTxtLength; ++i) { diff --git a/src/core/net/dns_types.hpp b/src/core/net/dns_types.hpp index 1cfbc1b7c..12e922bd2 100644 --- a/src/core/net/dns_types.hpp +++ b/src/core/net/dns_types.hpp @@ -1677,13 +1677,14 @@ public: /** * This static method tests if a buffer contains valid encoded TXT data. * - * @param[in] aTxtData The TXT data buffer. - * @param[in] aTxtLength The length of the TXT data buffer. + * @param[in] aTxtData The TXT data buffer. + * @param[in] aTxtLength The length of the TXT data buffer. + * @param[in] aAllowEmpty True if zero-length TXT data is allowed. * * @returns TRUE if @p aTxtData contains valid encoded TXT data, FALSE if not. * */ - static bool VerifyTxtData(const uint8_t *aTxtData, uint16_t aTxtLength); + static bool VerifyTxtData(const uint8_t *aTxtData, uint16_t aTxtLength, bool aAllowEmpty); } OT_TOOL_PACKED_END; diff --git a/src/core/net/srp_server.cpp b/src/core/net/srp_server.cpp index 865452818..3643f5c31 100644 --- a/src/core/net/srp_server.cpp +++ b/src/core/net/srp_server.cpp @@ -1526,7 +1526,7 @@ Error Server::Service::Description::SetTxtDataFromMessage(const Message &aMessag VerifyOrExit(txtData != nullptr, error = kErrorNoBufs); VerifyOrExit(aMessage.ReadBytes(aOffset, txtData, aLength) == aLength, error = kErrorParse); - VerifyOrExit(Dns::TxtRecord::VerifyTxtData(txtData, aLength), error = kErrorParse); + VerifyOrExit(Dns::TxtRecord::VerifyTxtData(txtData, aLength, /* aAllowEmpty */ false), error = kErrorParse); Instance::HeapFree(mTxtData); mTxtData = txtData;