diff --git a/src/core/net/dns_headers.cpp b/src/core/net/dns_headers.cpp index 1fbe68dd9..74a73b7e3 100644 --- a/src/core/net/dns_headers.cpp +++ b/src/core/net/dns_headers.cpp @@ -128,8 +128,6 @@ otError Name::AppendMultipleLabels(const char *aLabels, Message &aMessage) do { - VerifyOrExit(index < kMaxLength, error = OT_ERROR_INVALID_ARGS); - ch = aLabels[index]; if ((ch == kNullChar) || (ch == kLabelSeperatorChar)) @@ -149,6 +147,7 @@ otError Name::AppendMultipleLabels(const char *aLabels, Message &aMessage) ExitNow(); } + VerifyOrExit(index + 1 < kMaxEncodedLength, error = OT_ERROR_INVALID_ARGS); SuccessOrExit(error = AppendLabel(&aLabels[labelStartIndex], labelLength, aMessage)); labelStartIndex = index + 1; diff --git a/src/core/net/dns_headers.hpp b/src/core/net/dns_headers.hpp index bf127d055..ff3208ffd 100644 --- a/src/core/net/dns_headers.hpp +++ b/src/core/net/dns_headers.hpp @@ -487,8 +487,9 @@ class Name public: enum : uint8_t { - kMaxLabelLength = 63, ///< Max number of characters in a label. - kMaxLength = 255, ///< Max number of characters in a name. + kMaxLabelLength = 63, ///< Max number of characters in a label. + kMaxLength = 254, ///< Max number of characters in a name. + kMaxEncodedLength = 255, ///< Max length of an encoded name. }; /** diff --git a/tests/unit/test_dns.cpp b/tests/unit/test_dns.cpp index 742b5c8e5..252623771 100644 --- a/tests/unit/test_dns.cpp +++ b/tests/unit/test_dns.cpp @@ -88,6 +88,18 @@ void TestDnsName(void) {nullptr, sizeof(kEncodedName4), kEncodedName4, kLabels4, "."}, }; + static const char *kMaxLengthNames[] = { + "HereIsSomeoneHidden.MyHoldFromMeTaken.FromSelfHasMeDriven.MyLeadFromMeTaken." + "HereIsSomeoneHidden.AsLifeSweeterThanLife.TakesMeToGardenOfSoul.MyFortFromMeTaken." + "HereIsSomeoneHidden.LikeSugarInSugarCane.ASweetSugarTrader.MyShopFromMeTaken." + "SorcererAndMagicia.", + + "HereIsSomeoneHidden.MyHoldFromMeTaken.FromSelfHasMeDriven.MyLeadFromMeTaken." + "HereIsSomeoneHidden.AsLifeSweeterThanLife.TakesMeToGardenOfSoul.MyFortFromMeTaken." + "HereIsSomeoneHidden.LikeSugarInSugarCane.ASweetSugarTrader.MyShopFromMeTaken." + "SorcererAndMagicia", + }; + static const char *kInvalidNames[] = { "foo..bar", "..", @@ -104,6 +116,19 @@ void TestDnsName(void) "SorcererAndMagician.NoEyesCanEverSee.AnArtfulConjurer.MySenseFromMeTaken." "MyEyesWillNeverSee.BeautiesOfTheWholeWorld.BeholdWhoseVisionFine.MySightFromMeTaken" "PoemByRumiMolana", + + // Long name of 255 characters which ends with a dot + "HereIsSomeoneHidden.MyHoldFromMeTaken.FromSelfHasMeDriven.MyLeadFromMeTaken." + "HereIsSomeoneHidden.AsLifeSweeterThanLife.TakesMeToGardenOfSoul.MyFortFromMeTaken." + "HereIsSomeoneHidden.LikeSugarInSugarCane.ASweetSugarTrader.MyShopFromMeTaken." + "SorcererAndMagician.", + + // Long name of 254 characters which does not end with a dot + "HereIsSomeoneHidden.MyHoldFromMeTaken.FromSelfHasMeDriven.MyLeadFromMeTaken." + "HereIsSomeoneHidden.AsLifeSweeterThanLife.TakesMeToGardenOfSoul.MyFortFromMeTaken." + "HereIsSomeoneHidden.LikeSugarInSugarCane.ASweetSugarTrader.MyShopFromMeTaken." + "SorcererAndMagician", + }; printf("================================================================\n"); @@ -177,6 +202,28 @@ void TestDnsName(void) "Name::ReadName() did not fail with too small name buffer size"); } + printf("----------------------------------------------------------------\n"); + printf("Max length names:\n"); + + for (const char *&maxLengthName : kMaxLengthNames) + { + if (maxLengthName[strlen(maxLengthName) - 1] == '.') + { + VerifyOrQuit(strlen(maxLengthName) == Dns::Name::kMaxLength, "invalid max length string"); + } + else + { + VerifyOrQuit(strlen(maxLengthName) == Dns::Name::kMaxLength - 1, "invalid max length string"); + } + + IgnoreError(message->SetLength(0)); + + printf("\"%s\"\n", maxLengthName); + + VerifyOrQuit(Dns::Name::AppendName(maxLengthName, *message) == OT_ERROR_NONE, + "Name::AppendName() failed with max length name"); + } + printf("----------------------------------------------------------------\n"); printf("Invalid names:\n");