diff --git a/src/core/net/dns_types.cpp b/src/core/net/dns_types.cpp index 34412e3b2..d8a21dba9 100644 --- a/src/core/net/dns_types.cpp +++ b/src/core/net/dns_types.cpp @@ -639,6 +639,9 @@ Error Name::LabelIterator::ReadLabel(char *aLabelBuffer, uint8_t &aLabelLength, aLabelBuffer[mLabelLength] = kNullChar; aLabelLength = mLabelLength; + // Check that there is no `kNullChar` (`\0`) in the read label. + VerifyOrExit(StringLength(aLabelBuffer, mLabelLength) == mLabelLength, error = kErrorParse); + if (!aAllowDotCharInLabel) { VerifyOrExit(StringFind(aLabelBuffer, kLabelSeparatorChar) == nullptr, error = kErrorParse); @@ -1592,10 +1595,6 @@ Error PtrRecord::ReadPtrName(const Message &aMessage, aOffset = startOffset + sizeof(PtrRecord); SuccessOrExit(error = Name::ReadLabel(aMessage, aOffset, aLabelBuffer, aLabelBufferSize)); - // The first label of a PTR target (the service-instance or host label) - // must be non-empty. - VerifyOrExit(aLabelBuffer[0] != kNullChar, error = kErrorParse); - if (aNameBuffer != nullptr) { SuccessOrExit(error = Name::ReadName(aMessage, aOffset, aNameBuffer, aNameBufferSize)); diff --git a/tests/unit/test_dns.cpp b/tests/unit/test_dns.cpp index c4a1a2a6c..c0240c0ba 100644 --- a/tests/unit/test_dns.cpp +++ b/tests/unit/test_dns.cpp @@ -161,6 +161,14 @@ void TestDnsName(void) {"_s1._sub._srv._udp.default.service.arpa.", "_s1", "_sub._srv._udp", "default.service.arpa.", true}, }; + typedef uint8_t EncodedNameWithNullChar[6]; + + static const EncodedNameWithNullChar kEncodedNamesWithNullChar[] = { + {4, 0, 'a', 'b', 'c', 0}, // Null char at the start of the label + {4, 'a', 0, 'c', 'd', 0}, // Null char in the middle of the label + {4, 'a', 'b', 'c', 0, 0} // Null char in the end of the label + }; + printf("================================================================\n"); printf("TestDnsName()\n"); @@ -626,6 +634,22 @@ void TestDnsName(void) "012345678901234567890123456789012345678901234567890123456789012") == kErrorInvalidArgs); + printf("----------------------------------------------------------------\n"); + printf("Name::ReadLabel() when there is null-char \'\\0\' in the label\n"); + + for (const EncodedNameWithNullChar &encodedName : kEncodedNamesWithNullChar) + { + SuccessOrQuit(message->SetLength(0)); + SuccessOrQuit(message->AppendBytes(encodedName, sizeof(encodedName))); + + SuccessOrQuit(message->Read(0, buffer, message->GetLength())); + DumpBuffer("EncodedName", buffer, message->GetLength()); + + offset = 0; + labelLength = sizeof(label); + VerifyOrQuit(Dns::Name::ReadLabel(*message, offset, label, labelLength) == kErrorParse); + } + message->Free(); testFreeInstance(instance); }