Changeset View
Changeset View
Standalone View
Standalone View
src/seeder/test/dns_tests.cpp
Show First 20 Lines • Show All 48 Lines • ▼ Show 20 Lines | |||||
static void CheckParseName(const std::string &queryName) { | static void CheckParseName(const std::string &queryName) { | ||||
std::vector<uint8_t> nameField = CreateDNSQuestionNameField(queryName); | std::vector<uint8_t> nameField = CreateDNSQuestionNameField(queryName); | ||||
// Test when name field is too short to reach null-terminator | // Test when name field is too short to reach null-terminator | ||||
for (size_t nameFieldEndIndex = 0; nameFieldEndIndex < nameField.size(); | for (size_t nameFieldEndIndex = 0; nameFieldEndIndex < nameField.size(); | ||||
nameFieldEndIndex++) { | nameFieldEndIndex++) { | ||||
std::vector<char> parsedQueryName(MAX_QUERY_NAME_BUFFER_LENGTH, 0); | std::vector<char> parsedQueryName(MAX_QUERY_NAME_BUFFER_LENGTH, 0); | ||||
const uint8_t *nameFieldBegin = nameField.data(); | const uint8_t *nameFieldBegin = nameField.data(); | ||||
int ret = parse_name( | ParseNameStatus ret = parse_name( | ||||
&nameFieldBegin, nameFieldBegin + nameFieldEndIndex, | &nameFieldBegin, nameFieldBegin + nameFieldEndIndex, | ||||
nameField.data(), parsedQueryName.data(), parsedQueryName.size()); | nameField.data(), parsedQueryName.data(), parsedQueryName.size()); | ||||
BOOST_CHECK(ret != 0); | BOOST_CHECK(ret != ParseNameStatus::OK); | ||||
deadalnix: It is beyond the scope of that patch, but checking for the proper value would be better than… | |||||
} | } | ||||
// Test when the buffer size is too small | // Test when the buffer size is too small | ||||
size_t outputBufferSize = 0; | size_t outputBufferSize = 0; | ||||
while (outputBufferSize <= queryName.size()) { | while (outputBufferSize <= queryName.size()) { | ||||
std::vector<char> parsedQueryName(outputBufferSize, 0); | std::vector<char> parsedQueryName(outputBufferSize, 0); | ||||
const uint8_t *nameFieldBegin = nameField.data(); | const uint8_t *nameFieldBegin = nameField.data(); | ||||
int ret = parse_name(&nameFieldBegin, nameFieldBegin + nameField.size(), | ParseNameStatus ret = parse_name( | ||||
nameField.data(), parsedQueryName.data(), | &nameFieldBegin, nameFieldBegin + nameField.size(), | ||||
parsedQueryName.size()); | nameField.data(), parsedQueryName.data(), parsedQueryName.size()); | ||||
BOOST_CHECK(ret != 0); | BOOST_CHECK(ret != ParseNameStatus::OK); | ||||
outputBufferSize++; | outputBufferSize++; | ||||
} | } | ||||
// Happy path | // Happy path | ||||
while (outputBufferSize <= MAX_QUERY_NAME_BUFFER_LENGTH) { | while (outputBufferSize <= MAX_QUERY_NAME_BUFFER_LENGTH) { | ||||
std::vector<char> parsedQueryName(outputBufferSize, 0); | std::vector<char> parsedQueryName(outputBufferSize, 0); | ||||
const uint8_t *nameFieldBegin = nameField.data(); | const uint8_t *nameFieldBegin = nameField.data(); | ||||
int ret = parse_name(&nameFieldBegin, nameFieldBegin + nameField.size(), | ParseNameStatus ret = parse_name( | ||||
nameField.data(), parsedQueryName.data(), | &nameFieldBegin, nameFieldBegin + nameField.size(), | ||||
parsedQueryName.size()); | nameField.data(), parsedQueryName.data(), parsedQueryName.size()); | ||||
BOOST_CHECK_EQUAL(ret, 0); | BOOST_CHECK_EQUAL(ret, ParseNameStatus::OK); | ||||
BOOST_CHECK_EQUAL(parsedQueryName.data(), queryName); | BOOST_CHECK_EQUAL(parsedQueryName.data(), queryName); | ||||
outputBufferSize++; | outputBufferSize++; | ||||
} | } | ||||
} | } | ||||
static void CheckParseNameError( | static void CheckParseNameError( | ||||
const std::string &queryName, const int expectedError, | const std::string &queryName, const ParseNameStatus expectedError, | ||||
const size_t &outputBufferSize = MAX_QUERY_NAME_BUFFER_LENGTH) { | const size_t &outputBufferSize = MAX_QUERY_NAME_BUFFER_LENGTH) { | ||||
std::vector<uint8_t> nameField = CreateDNSQuestionNameField(queryName); | std::vector<uint8_t> nameField = CreateDNSQuestionNameField(queryName); | ||||
std::vector<char> parsedQueryName(outputBufferSize, 0); | std::vector<char> parsedQueryName(outputBufferSize, 0); | ||||
const uint8_t *nameFieldBegin = nameField.data(); | const uint8_t *nameFieldBegin = nameField.data(); | ||||
int ret = parse_name(&nameFieldBegin, nameFieldBegin + nameField.size(), | ParseNameStatus ret = parse_name( | ||||
nameField.data(), parsedQueryName.data(), | &nameFieldBegin, nameFieldBegin + nameField.size(), nameField.data(), | ||||
parsedQueryName.size()); | parsedQueryName.data(), parsedQueryName.size()); | ||||
BOOST_CHECK_EQUAL(ret, expectedError); | BOOST_CHECK_EQUAL(ret, expectedError); | ||||
} | } | ||||
BOOST_AUTO_TEST_CASE(parse_name_tests) { | BOOST_AUTO_TEST_CASE(parse_name_tests) { | ||||
CheckParseName("www.domain.com"); | CheckParseName("www.domain.com"); | ||||
CheckParseName("domain.com"); | CheckParseName("domain.com"); | ||||
CheckParseName("sub1.sub2.domain.co.uk"); | CheckParseName("sub1.sub2.domain.co.uk"); | ||||
// Shortest valid domain name is 1 char followed by the extension | // Shortest valid domain name is 1 char followed by the extension | ||||
CheckParseName("a.co"); | CheckParseName("a.co"); | ||||
// Domain name with valid non-alphanumeric character | // Domain name with valid non-alphanumeric character | ||||
CheckParseName("my-domain.com"); | CheckParseName("my-domain.com"); | ||||
} | } | ||||
BOOST_AUTO_TEST_CASE(parse_name_label_tests) { | BOOST_AUTO_TEST_CASE(parse_name_label_tests) { | ||||
// Check behavior for name with maximum length label | // Check behavior for name with maximum length label | ||||
const std::string maxLengthLabel(MAX_LABEL_LENGTH, 'a'); | const std::string maxLengthLabel(MAX_LABEL_LENGTH, 'a'); | ||||
CheckParseName("www." + maxLengthLabel + ".com"); | CheckParseName("www." + maxLengthLabel + ".com"); | ||||
// Check that an oversized label causes an error | // Check that an oversized label causes an error | ||||
CheckParseNameError("www." + maxLengthLabel + "a.com", -1); | CheckParseNameError("www." + maxLengthLabel + "a.com", | ||||
ParseNameStatus::InputError); | |||||
} | } | ||||
BOOST_AUTO_TEST_CASE(parse_name_qname_length_tests) { | BOOST_AUTO_TEST_CASE(parse_name_qname_length_tests) { | ||||
const std::string maxLengthLabel(MAX_LABEL_LENGTH, 'a'); | const std::string maxLengthLabel(MAX_LABEL_LENGTH, 'a'); | ||||
// Check behavior for a name that is the maximum length | // Check behavior for a name that is the maximum length | ||||
std::string maxLengthQName = maxLengthLabel + '.' + maxLengthLabel + '.' + | std::string maxLengthQName = maxLengthLabel + '.' + maxLengthLabel + '.' + | ||||
maxLengthLabel + '.' + maxLengthLabel; | maxLengthLabel + '.' + maxLengthLabel; | ||||
BOOST_CHECK_EQUAL(maxLengthQName.size(), MAX_QUERY_NAME_LENGTH); | BOOST_CHECK_EQUAL(maxLengthQName.size(), MAX_QUERY_NAME_LENGTH); | ||||
CheckParseName(maxLengthQName); | CheckParseName(maxLengthQName); | ||||
// Check that a query name that is too long causes an error | // Check that a query name that is too long causes an error | ||||
std::string overSizedQName = maxLengthQName; | std::string overSizedQName = maxLengthQName; | ||||
// Split the last label into two while adding an extra character to make | // Split the last label into two while adding an extra character to make | ||||
// sure the function does not error because of an oversized label | // sure the function does not error because of an oversized label | ||||
overSizedQName.insert(overSizedQName.end() - 3, '.'); | overSizedQName.insert(overSizedQName.end() - 3, '.'); | ||||
// Allocates an extra large buffer to guarantee an error is not caused by | // Allocates an extra large buffer to guarantee an error is not caused by | ||||
// the buffer size | // the buffer size | ||||
CheckParseNameError(overSizedQName, -1, 2 * overSizedQName.size()); | CheckParseNameError(overSizedQName, ParseNameStatus::InputError, | ||||
2 * overSizedQName.size()); | |||||
} | } | ||||
BOOST_AUTO_TEST_SUITE_END() | BOOST_AUTO_TEST_SUITE_END() |
It is beyond the scope of that patch, but checking for the proper value would be better than this.