From: Mukund Sivaraman Date: Fri, 21 Dec 2012 06:22:27 +0000 (+0530) Subject: [2535] Add charStringToString() to convert a CharString to a DNS textual representation X-Git-Tag: bind10-1.0.0-rc-release~99^2~25^2~1^2~14 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=77b42eabd7630b5ba7f5f9fa383de73e0e7fe49d;p=thirdparty%2Fkea.git [2535] Add charStringToString() to convert a CharString to a DNS textual representation --- diff --git a/src/lib/dns/rdata/generic/detail/char_string.cc b/src/lib/dns/rdata/generic/detail/char_string.cc index fb4c9b41db..dcee08a905 100644 --- a/src/lib/dns/rdata/generic/detail/char_string.cc +++ b/src/lib/dns/rdata/generic/detail/char_string.cc @@ -91,6 +91,29 @@ strToCharString(const MasterToken::StringRegion& str_region, result[0] = result.size() - 1; } +std::string +charStringToString(const CharString& char_string) { + std::string s; + for (CharString::const_iterator it = char_string.begin() + 1; + it != char_string.end(); ++it) { + const uint8_t ch = *it; + if ((ch < 0x20) || (ch >= 0x7f)) { + // convert to escaped \xxx (decimal) format + s.push_back('\\'); + s.push_back('0' + ((ch / 100) % 10)); + s.push_back('0' + ((ch / 10) % 10)); + s.push_back('0' + (ch % 10)); + continue; + } + if ((ch == '"') || (ch == ';') || (ch == '\\')) { + s.push_back('\\'); + } + s.push_back(ch); + } + + return (s); +} + } // end of detail } // end of generic } // end of rdata diff --git a/src/lib/dns/rdata/generic/detail/char_string.h b/src/lib/dns/rdata/generic/detail/char_string.h index 702af04ed5..b369f40459 100644 --- a/src/lib/dns/rdata/generic/detail/char_string.h +++ b/src/lib/dns/rdata/generic/detail/char_string.h @@ -17,6 +17,7 @@ #include +#include #include #include @@ -51,6 +52,20 @@ typedef std::vector CharString; void strToCharString(const MasterToken::StringRegion& str_region, CharString& result); +/// \brief Convert a CharString into a textual DNS character-string. +/// +/// This method converts a binary 8-bit representation of a DNS +/// character string into a textual string representation, escaping any +/// special characters in the process. For example, characters like +/// double-quotes, semi-colon and backspace are prefixed with backspace +/// character, and characters not in the printable range of [0x20, 0x7e] +/// (inclusive) are converted to the \xxx 3-digit decimal +/// representation. +/// +/// \param char_string The \c CharString to convert. +/// \return A string representation of \c char_string. +std::string charStringToString(const CharString& char_string); + } // namespace detail } // namespace generic } // namespace rdata diff --git a/src/lib/dns/tests/rdata_char_string_unittest.cc b/src/lib/dns/tests/rdata_char_string_unittest.cc index 9d236229c1..75263916da 100644 --- a/src/lib/dns/tests/rdata_char_string_unittest.cc +++ b/src/lib/dns/tests/rdata_char_string_unittest.cc @@ -26,6 +26,7 @@ using namespace isc::dns; using namespace isc::dns::rdata; using isc::dns::rdata::generic::detail::CharString; using isc::dns::rdata::generic::detail::strToCharString; +using isc::dns::rdata::generic::detail::charStringToString; using isc::util::unittests::matchWireData; namespace { @@ -144,4 +145,61 @@ TEST_F(CharStringTest, badDDD) { InvalidRdataText); } +TEST_F(CharStringTest, charStringToString) { + const uint8_t double_quotes_buf[] = { + sizeof("Test\"Test\"") - 1, + 'T', 'e', 's', 't', '"', 'T', 'e', 's', 't', '"' + }; + const CharString double_quotes + (double_quotes_buf, double_quotes_buf + sizeof(double_quotes_buf)); + EXPECT_EQ("Test\\\"Test\\\"", + charStringToString(double_quotes)); + + const uint8_t semicolon_buf[] = { + sizeof("Test;Test") - 1, + 'T', 'e', 's', 't', ';', 'T', 'e', 's', 't' + }; + const CharString semicolon + (semicolon_buf, semicolon_buf + sizeof(semicolon_buf)); + EXPECT_EQ("Test\\;Test", + charStringToString(semicolon)); + + const uint8_t backslash_buf[] = { + sizeof("Test\\Test") - 1, + 'T', 'e', 's', 't', '\\', 'T', 'e', 's', 't' + }; + const CharString backslash + (backslash_buf, backslash_buf + sizeof(backslash_buf)); + EXPECT_EQ("Test\\\\Test", + charStringToString(backslash)); + + const uint8_t before_x20_buf[] = { + sizeof("Test\x1fTest") - 1, + 'T', 'e', 's', 't', 0x1f, 'T', 'e', 's', 't' + }; + const CharString before_x20 + (before_x20_buf, before_x20_buf + sizeof(before_x20_buf)); + EXPECT_EQ("Test\\031Test", + charStringToString(before_x20)); + + const uint8_t from_x20_to_x7e_buf[] = { + sizeof("Test ~ Test") - 1, + 'T', 'e', 's', 't', ' ', '~', ' ', 'T', 'e', 's', 't' + }; + const CharString from_x20_to_x7e + (from_x20_to_x7e_buf, + from_x20_to_x7e_buf + sizeof(from_x20_to_x7e_buf)); + EXPECT_EQ("Test ~ Test", + charStringToString(from_x20_to_x7e)); + + const uint8_t after_0x7e_buf[] = { + sizeof("Test\x7fTest") - 1, + 'T', 'e', 's', 't', 0x7f, 'T', 'e', 's', 't' + }; + const CharString after_0x7e + (after_0x7e_buf, after_0x7e_buf + sizeof(after_0x7e_buf)); + EXPECT_EQ("Test\\127Test", + charStringToString(after_0x7e)); +} + } // unnamed namespace