Bitcoin ABC 0.30.5
P2P Digital Currency
parse_name_tests.cpp
Go to the documentation of this file.
1// Copyright (c) 2019 The Bitcoin developers
2// Distributed under the MIT software license, see the accompanying
3// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
5#include <seeder/dns.h>
7#include <seeder/test/util.h>
8
9#include <ostream>
10#include <string>
11#include <vector>
12
13#include <boost/test/unit_test.hpp>
14
15std::ostream &operator<<(std::ostream &os, const ParseNameStatus &status) {
16 os << to_integral(status);
17 return os;
18}
19
20BOOST_AUTO_TEST_SUITE(parse_name_tests)
21
22static void CheckParseName(const std::string &queryName) {
23 std::vector<uint8_t> nameField = CreateDNSQuestionNameField(queryName);
24
25 // Test when name field is too short to reach null-terminator
26 for (size_t nameFieldEndIndex = 0; nameFieldEndIndex < nameField.size();
27 nameFieldEndIndex++) {
28 std::vector<char> parsedQueryName(MAX_QUERY_NAME_BUFFER_LENGTH, 0);
29 const uint8_t *nameFieldBegin = nameField.data();
31 &nameFieldBegin, nameFieldBegin + nameFieldEndIndex,
32 nameField.data(), parsedQueryName.data(), parsedQueryName.size());
33
35 }
36
37 // Test when the buffer size is too small
38 size_t outputBufferSize = 0;
39 while (outputBufferSize <= queryName.size()) {
40 std::vector<char> parsedQueryName(outputBufferSize, 0);
41 const uint8_t *nameFieldBegin = nameField.data();
43 &nameFieldBegin, nameFieldBegin + nameField.size(),
44 nameField.data(), parsedQueryName.data(), parsedQueryName.size());
46 outputBufferSize++;
47 }
48
49 // Happy path
50 while (outputBufferSize <= MAX_QUERY_NAME_BUFFER_LENGTH) {
51 std::vector<char> parsedQueryName(outputBufferSize, 0);
52 const uint8_t *nameFieldBegin = nameField.data();
54 &nameFieldBegin, nameFieldBegin + nameField.size(),
55 nameField.data(), parsedQueryName.data(), parsedQueryName.size());
57 BOOST_CHECK_EQUAL(parsedQueryName.data(), queryName);
58 outputBufferSize++;
59 }
60}
61
63 const std::string &queryName, const ParseNameStatus expectedError,
64 const size_t &outputBufferSize = MAX_QUERY_NAME_BUFFER_LENGTH) {
65 std::vector<uint8_t> nameField = CreateDNSQuestionNameField(queryName);
66
67 std::vector<char> parsedQueryName(outputBufferSize, 0);
68 const uint8_t *nameFieldBegin = nameField.data();
70 &nameFieldBegin, nameFieldBegin + nameField.size(), nameField.data(),
71 parsedQueryName.data(), parsedQueryName.size());
72
73 BOOST_CHECK_EQUAL(ret, expectedError);
74}
75
76BOOST_AUTO_TEST_CASE(parse_name_simple_tests) {
77 CheckParseName("www.domain.com");
78 CheckParseName("domain.com");
79 CheckParseName("sub1.sub2.domain.co.uk");
80 // Shortest valid domain name is 1 char followed by the extension
81 CheckParseName("a.co");
82 // Domain name with valid non-alphanumeric character
83 CheckParseName("my-domain.com");
84}
85
86BOOST_AUTO_TEST_CASE(parse_name_label_tests) {
87 // Check behavior for name with maximum length label
88 const std::string maxLengthLabel(MAX_LABEL_LENGTH, 'a');
89 CheckParseName("www." + maxLengthLabel + ".com");
90
91 // Check that an oversized label causes an error
92 CheckParseNameError("www." + maxLengthLabel + "a.com",
94}
95
96BOOST_AUTO_TEST_CASE(parse_name_qname_length_tests) {
97 const std::string maxLengthLabel(MAX_LABEL_LENGTH, 'a');
98
99 // Check behavior for a name that is the maximum length
100 std::string maxLengthQName = maxLengthLabel + '.' + maxLengthLabel + '.' +
101 maxLengthLabel + '.' + maxLengthLabel;
102 BOOST_CHECK_EQUAL(maxLengthQName.size(), MAX_QUERY_NAME_LENGTH);
103 CheckParseName(maxLengthQName);
104
105 // Check that a query name that is too long causes an error
106 std::string overSizedQName = maxLengthQName;
107 // Split the last label into two while adding an extra character to make
108 // sure the function does not error because of an oversized label
109 overSizedQName.insert(overSizedQName.end() - 3, '.');
110 // Allocates an extra large buffer to guarantee an error is not caused by
111 // the buffer size
113 2 * overSizedQName.size());
114}
115
116BOOST_AUTO_TEST_SUITE_END()
ParseNameStatus parse_name(const uint8_t **inpos, const uint8_t *inend, const uint8_t *inbuf, char *buf, size_t bufsize)
Definition: dns.cpp:66
ParseNameStatus
Definition: dns.h:38
constexpr int MAX_LABEL_LENGTH
Definition: dns.h:11
constexpr int MAX_QUERY_NAME_LENGTH
Definition: dns.h:12
constexpr int MAX_QUERY_NAME_BUFFER_LENGTH
Definition: dns.h:14
static std::vector< uint8_t > CreateDNSQuestionNameField(const std::string &queryName)
Definition: dns_util.h:15
Implement std::hash so RCUPtr can be used as a key for maps or sets.
Definition: rcu.h:259
#define BOOST_CHECK_EQUAL(v1, v2)
Definition: object.cpp:18
#define BOOST_CHECK(expr)
Definition: object.cpp:17
std::ostream & operator<<(std::ostream &os, const ParseNameStatus &status)
static void CheckParseName(const std::string &queryName)
BOOST_AUTO_TEST_CASE(parse_name_simple_tests)
static void CheckParseNameError(const std::string &queryName, const ParseNameStatus expectedError, const size_t &outputBufferSize=MAX_QUERY_NAME_BUFFER_LENGTH)
constexpr std::underlying_type< E >::type to_integral(E e)
Definition: util.h:11