diff --git a/src/seeder/dns.cpp b/src/seeder/dns.cpp --- a/src/seeder/dns.cpp +++ b/src/seeder/dns.cpp @@ -78,6 +78,11 @@ } // add dot in output if (!init) { + // The maximum size of a query name is 255. The buffer must have + // room for at least the '.' and a valid non-'.' character + if (bufused > 253) { + return -1; + } if (bufused == bufsize - 1) { return -2; } @@ -103,7 +108,7 @@ } // copy label while (octet) { - if (*inpos == inend) { + if (*inpos == inend || bufused > 254) { return -1; } if (bufused == bufsize - 1) { diff --git a/src/seeder/test/seeder_tests.cpp b/src/seeder/test/seeder_tests.cpp --- a/src/seeder/test/seeder_tests.cpp +++ b/src/seeder/test/seeder_tests.cpp @@ -112,7 +112,7 @@ CheckParseName("my-domain.com"); } -BOOST_AUTO_TEST_CASE(parse_name_label_tests) { +BOOST_AUTO_TEST_CASE(parse_name_label_and_name_length_tests) { // Check behavior for name with maximum length label std::string maxLengthLabel; for (size_t i = 0; i < MAX_LABEL_LENGTH; i++) { @@ -123,6 +123,17 @@ // Check that an oversized label causes an error CheckParseNameError("www." + maxLengthLabel + "a.com", -1); + + // Check behavior for a name that is the maximum length + std::string maxLengthQName = maxLengthLabel + '.' + maxLengthLabel + '.' + + maxLengthLabel + '.' + maxLengthLabel; + BOOST_CHECK_EQUAL(maxLengthQName.size(), MAX_QUERY_NAME_LENGTH); + CheckParseName(maxLengthQName); + + // Check that a query name that is too long causes an error + // Allocates an extra large buffer to guarantee an error is not caused by + // the buffer size + CheckParseNameError(maxLengthQName + "a", -1, 2 * maxLengthQName.size()); } BOOST_AUTO_TEST_SUITE_END()