rdata_txt_unittest.cc 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. // Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
  2. //
  3. // Permission to use, copy, modify, and/or distribute this software for any
  4. // purpose with or without fee is hereby granted, provided that the above
  5. // copyright notice and this permission notice appear in all copies.
  6. //
  7. // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
  8. // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  9. // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
  10. // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  11. // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  12. // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  13. // PERFORMANCE OF THIS SOFTWARE.
  14. #include <util/buffer.h>
  15. #include <dns/exceptions.h>
  16. #include <dns/messagerenderer.h>
  17. #include <dns/rdata.h>
  18. #include <dns/rdataclass.h>
  19. #include <dns/rrclass.h>
  20. #include <dns/rrtype.h>
  21. #include <gtest/gtest.h>
  22. #include <dns/tests/unittest_util.h>
  23. #include <dns/tests/rdata_unittest.h>
  24. using isc::UnitTestUtil;
  25. using namespace std;
  26. using namespace isc::dns;
  27. using namespace isc::util;
  28. using namespace isc::dns::rdata;
  29. namespace {
  30. const generic::TXT rdata_txt("Test String");
  31. const generic::TXT rdata_txt_empty("");
  32. const generic::TXT rdata_txt_quoated("\"Test String\"");
  33. const uint8_t wiredata_txt[] = {
  34. sizeof("Test String") - 1,
  35. 'T', 'e', 's', 't', ' ', 'S', 't', 'r', 'i', 'n', 'g'
  36. };
  37. const uint8_t wiredata_nulltxt[] = { 0 };
  38. vector<uint8_t> wiredata_longesttxt(256, 'a');
  39. class Rdata_TXT_Test : public RdataTest {
  40. protected:
  41. Rdata_TXT_Test() {
  42. wiredata_longesttxt[0] = 255; // adjust length
  43. }
  44. };
  45. TEST_F(Rdata_TXT_Test, createFromText) {
  46. // normal case is covered in toWireBuffer.
  47. // surrounding double-quotes shouldn't change the result.
  48. EXPECT_EQ(0, rdata_txt.compare(rdata_txt_quoated));
  49. // Null character-string.
  50. obuffer.clear();
  51. generic::TXT(string("")).toWire(obuffer);
  52. EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
  53. obuffer.getData(), obuffer.getLength(),
  54. wiredata_nulltxt, sizeof(wiredata_nulltxt));
  55. // Longest possible character-string.
  56. obuffer.clear();
  57. generic::TXT(string(255, 'a')).toWire(obuffer);
  58. EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
  59. obuffer.getData(), obuffer.getLength(),
  60. &wiredata_longesttxt[0], wiredata_longesttxt.size());
  61. // Too long text for a valid character-string.
  62. EXPECT_THROW(generic::TXT(string(256, 'a')), CharStringTooLong);
  63. // The escape character makes the double quote a part of character-string,
  64. // so this is invalid input and should be rejected.
  65. EXPECT_THROW(generic::TXT("\"Test String\\\""), InvalidRdataText);
  66. // Terminating double-quote is provided, so this is valid, but in this
  67. // version of implementation we reject escaped characters.
  68. EXPECT_THROW(generic::TXT("\"Test String\\\"\""), InvalidRdataText);
  69. }
  70. void
  71. makeLargest(vector<uint8_t>& data) {
  72. uint8_t ch = 0;
  73. // create 255 sets of character-strings, each of which has the longest
  74. // length (255bytes string + 1-byte length field)
  75. for (int i = 0; i < 255; ++i, ++ch) {
  76. data.push_back(255);
  77. data.insert(data.end(), 255, ch);
  78. }
  79. // the last character-string should be 255 bytes (including the one-byte
  80. // length field) in length so that the total length should be in the range
  81. // of 16-bit integers.
  82. data.push_back(254);
  83. data.insert(data.end(), 254, ch);
  84. assert(data.size() == 65535);
  85. }
  86. TEST_F(Rdata_TXT_Test, createFromWire) {
  87. EXPECT_EQ(0, rdata_txt.compare(
  88. *rdataFactoryFromFile(RRType("TXT"), RRClass("IN"),
  89. "rdata_txt_fromWire1")));
  90. // Empty character string
  91. EXPECT_EQ(0, rdata_txt_empty.compare(
  92. *rdataFactoryFromFile(RRType("TXT"), RRClass("IN"),
  93. "rdata_txt_fromWire2.wire")));
  94. // Multiple character strings
  95. obuffer.clear();
  96. rdataFactoryFromFile(RRType("TXT"), RRClass("IN"),
  97. "rdata_txt_fromWire3.wire")->toWire(obuffer);
  98. // the result should be 'wiredata_txt' repeated twice
  99. vector<uint8_t> expected_data(wiredata_txt, wiredata_txt +
  100. sizeof(wiredata_txt));
  101. expected_data.insert(expected_data.end(), wiredata_txt,
  102. wiredata_txt + sizeof(wiredata_txt));
  103. EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
  104. obuffer.getData(), obuffer.getLength(),
  105. &expected_data[0], expected_data.size());
  106. // Largest length of data. There's nothing special, but should be
  107. // constructed safely, and the content should be identical to the original
  108. // data.
  109. vector<uint8_t> largest_txt_data;
  110. makeLargest(largest_txt_data);
  111. InputBuffer ibuffer(&largest_txt_data[0], largest_txt_data.size());
  112. generic::TXT largest_txt(ibuffer, largest_txt_data.size());
  113. obuffer.clear();
  114. largest_txt.toWire(obuffer);
  115. EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
  116. obuffer.getData(), obuffer.getLength(),
  117. &largest_txt_data[0], largest_txt_data.size());
  118. // rdlen parameter is out of range. This is a rare event because we'd
  119. // normally call the constructor via a polymorphic wrapper, where the
  120. // length is validated. But this should be checked explicitly.
  121. InputBuffer ibuffer2(&largest_txt_data[0], largest_txt_data.size());
  122. EXPECT_THROW(generic::TXT(ibuffer2, 65536), InvalidRdataLength);
  123. // RDATA is empty, which is invalid for TXT.
  124. EXPECT_THROW(rdataFactoryFromFile(RRType("TXT"), RRClass("IN"),
  125. "rdata_txt_fromWire4.wire"),
  126. DNSMessageFORMERR);
  127. // character-string length is too large, which could cause overrun.
  128. EXPECT_THROW(rdataFactoryFromFile(RRType("TXT"), RRClass("IN"),
  129. "rdata_txt_fromWire5.wire"),
  130. DNSMessageFORMERR);
  131. }
  132. TEST_F(Rdata_TXT_Test, toWireBuffer) {
  133. rdata_txt.toWire(obuffer);
  134. EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
  135. obuffer.getData(), obuffer.getLength(),
  136. wiredata_txt, sizeof(wiredata_txt));
  137. }
  138. TEST_F(Rdata_TXT_Test, toText) {
  139. EXPECT_EQ("\"Test String\"", rdata_txt.toText());
  140. }
  141. }