diff options
Diffstat (limited to 'src/lib/dns/tests/rdata_char_string_data_unittest.cc')
-rw-r--r-- | src/lib/dns/tests/rdata_char_string_data_unittest.cc | 181 |
1 files changed, 181 insertions, 0 deletions
diff --git a/src/lib/dns/tests/rdata_char_string_data_unittest.cc b/src/lib/dns/tests/rdata_char_string_data_unittest.cc new file mode 100644 index 0000000..4ffeadb --- /dev/null +++ b/src/lib/dns/tests/rdata_char_string_data_unittest.cc @@ -0,0 +1,181 @@ +// Copyright (C) 2014-2015 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <config.h> + +#include <util/unittests/wiredata.h> + +#include <dns/exceptions.h> +#include <dns/rdata.h> +#include <dns/rdata/generic/detail/char_string.h> +#include <util/buffer.h> + +#include <gtest/gtest.h> + +#include <string> +#include <vector> + +using namespace isc::dns; +using namespace isc::dns::rdata; +using isc::dns::rdata::generic::detail::CharStringData; +using isc::dns::rdata::generic::detail::stringToCharStringData; +using isc::dns::rdata::generic::detail::charStringDataToString; +using isc::dns::rdata::generic::detail::compareCharStringDatas; +using isc::util::unittests::matchWireData; + +namespace { +const uint8_t test_charstr[] = { + 'T', 'e', 's', 't', ' ', 'S', 't', 'r', 'i', 'n', 'g' +}; + +class CharStringDataTest : public ::testing::Test { +protected: + CharStringDataTest() : + // char-string representation for test data using two types of escape + // ('r' = 114) + test_str("Test\\ St\\114ing") + { + str_region.beg = &test_str[0]; + str_region.len = test_str.size(); + } + CharStringData chstr; // place holder + const std::string test_str; + MasterToken::StringRegion str_region; +}; + +MasterToken::StringRegion +createStringRegion(const std::string& str) { + MasterToken::StringRegion region; + region.beg = &str[0]; // note std ensures this works even if str is empty + region.len = str.size(); + return (region); +} + +TEST_F(CharStringDataTest, normalConversion) { + uint8_t tmp[3]; // placeholder for expected sequence + + stringToCharStringData(str_region, chstr); + matchWireData(test_charstr, sizeof(test_charstr), &chstr[0], chstr.size()); + + // Empty string + chstr.clear(); + stringToCharStringData(createStringRegion(""), chstr); + EXPECT_TRUE(chstr.empty()); + + // Possible largest char string + chstr.clear(); + std::string long_str(255, 'x'); + stringToCharStringData(createStringRegion(long_str), chstr); + std::vector<uint8_t> expected; + expected.insert(expected.end(), long_str.begin(), long_str.end()); + matchWireData(&expected[0], expected.size(), &chstr[0], chstr.size()); + + // Escaped '\' + chstr.clear(); + tmp[0] = '\\'; + stringToCharStringData(createStringRegion("\\\\"), chstr); + matchWireData(tmp, 1, &chstr[0], chstr.size()); + + // Boundary values for \DDD + chstr.clear(); + tmp[0] = 0; + stringToCharStringData(createStringRegion("\\000"), chstr); + matchWireData(tmp, 1, &chstr[0], chstr.size()); + + chstr.clear(); + stringToCharStringData(createStringRegion("\\255"), chstr); + tmp[0] = 255; + matchWireData(tmp, 1, &chstr[0], chstr.size()); + + // Another digit follows DDD; it shouldn't cause confusion + chstr.clear(); + stringToCharStringData(createStringRegion("\\2550"), chstr); + tmp[1] = '0'; + matchWireData(tmp, 2, &chstr[0], chstr.size()); +} + +TEST_F(CharStringDataTest, badConversion) { + // input string ending with (non escaped) '\' + chstr.clear(); + EXPECT_THROW(stringToCharStringData(createStringRegion("foo\\"), chstr), + InvalidRdataText); +} + +TEST_F(CharStringDataTest, badDDD) { + // Check various type of bad form of \DDD + + // Not a number + EXPECT_THROW(stringToCharStringData(createStringRegion("\\1a2"), chstr), + InvalidRdataText); + EXPECT_THROW(stringToCharStringData(createStringRegion("\\12a"), chstr), + InvalidRdataText); + + // Not in the range of uint8_t + EXPECT_THROW(stringToCharStringData(createStringRegion("\\256"), chstr), + InvalidRdataText); + + // Short buffer + EXPECT_THROW(stringToCharStringData(createStringRegion("\\42"), chstr), + InvalidRdataText); +} + +const struct TestData { + const char *data; + const char *expected; +} conversion_data[] = { + {"Test\"Test", "Test\\\"Test"}, + {"Test;Test", "Test\\;Test"}, + {"Test\\Test", "Test\\\\Test"}, + {"Test\x1fTest", "Test\\031Test"}, + {"Test ~ Test", "Test ~ Test"}, + {"Test\x7fTest", "Test\\127Test"}, + {NULL, NULL} +}; + +TEST_F(CharStringDataTest, charStringDataToString) { + for (const TestData* cur = conversion_data; cur->data != NULL; ++cur) { + uint8_t idata[32]; + size_t length = std::strlen(cur->data); + ASSERT_LT(length, sizeof(idata)); + std::memcpy(idata, cur->data, length); + const CharStringData test_data(idata, idata + length); + EXPECT_EQ(cur->expected, charStringDataToString(test_data)); + } +} + +TEST_F(CharStringDataTest, compareCharStringData) { + CharStringData charstr; + CharStringData charstr2; + CharStringData charstr_small1; + CharStringData charstr_small2; + CharStringData charstr_large1; + CharStringData charstr_large2; + CharStringData charstr_empty; + + stringToCharStringData(createStringRegion("test string"), charstr); + stringToCharStringData(createStringRegion("test string"), charstr2); + stringToCharStringData(createStringRegion("test strin"), charstr_small1); + stringToCharStringData(createStringRegion("test strina"), charstr_small2); + stringToCharStringData(createStringRegion("test stringa"), charstr_large1); + stringToCharStringData(createStringRegion("test strinz"), charstr_large2); + + EXPECT_EQ(0, compareCharStringDatas(charstr, charstr2)); + EXPECT_EQ(0, compareCharStringDatas(charstr2, charstr)); + EXPECT_EQ(1, compareCharStringDatas(charstr, charstr_small1)); + EXPECT_EQ(1, compareCharStringDatas(charstr, charstr_small2)); + EXPECT_EQ(-1, compareCharStringDatas(charstr, charstr_large1)); + EXPECT_EQ(-1, compareCharStringDatas(charstr, charstr_large2)); + EXPECT_EQ(-1, compareCharStringDatas(charstr_small1, charstr)); + EXPECT_EQ(-1, compareCharStringDatas(charstr_small2, charstr)); + EXPECT_EQ(1, compareCharStringDatas(charstr_large1, charstr)); + EXPECT_EQ(1, compareCharStringDatas(charstr_large2, charstr)); + + EXPECT_EQ(-1, compareCharStringDatas(charstr_empty, charstr)); + EXPECT_EQ(1, compareCharStringDatas(charstr, charstr_empty)); + EXPECT_EQ(0, compareCharStringDatas(charstr_empty, charstr_empty)); +} + +} // unnamed namespace |