diff options
-rw-r--r-- | src/lib/dns/labelsequence.cc | 5 | ||||
-rw-r--r-- | src/lib/dns/labelsequence.h | 16 | ||||
-rw-r--r-- | src/lib/dns/name.cc | 27 | ||||
-rw-r--r-- | src/lib/dns/name.h | 27 | ||||
-rw-r--r-- | src/lib/dns/tests/labelsequence_unittest.cc | 21 |
5 files changed, 94 insertions, 2 deletions
diff --git a/src/lib/dns/labelsequence.cc b/src/lib/dns/labelsequence.cc index d6521e0bab..712a5eb14f 100644 --- a/src/lib/dns/labelsequence.cc +++ b/src/lib/dns/labelsequence.cc @@ -112,5 +112,10 @@ LabelSequence::getHash(bool case_sensitive) const { return (hash_val); } +std::string +LabelSequence::toText() const { + return (name_.toText(!isAbsolute(), first_label_, last_label_)); +} + } // end namespace dns } // end namespace isc diff --git a/src/lib/dns/labelsequence.h b/src/lib/dns/labelsequence.h index 12fb4f4bc6..f9711c8f1c 100644 --- a/src/lib/dns/labelsequence.h +++ b/src/lib/dns/labelsequence.h @@ -123,6 +123,22 @@ public: /// \return The number of labels size_t getLabelCount() const { return (last_label_ - first_label_); } + /// \brief Convert the LabelSequence to a string. + /// + /// This method returns a <code>std::string</code> object representing the + /// LabelSequence as a string. The returned string ends with a dot + /// '.' if the label sequence is absolute. + /// + /// This function assumes the underlying name is in proper + /// uncompressed wire format. If it finds an unexpected label + /// character including compression pointer, an exception of class + /// \c BadLabelType will be thrown. In addition, if resource + /// allocation for the result string fails, a corresponding standard + /// exception will be thrown. + // + /// \return a string representation of the <code>LabelSequence</code>. + std::string toText() const; + /// \brief Returns the original Name object associated with this /// LabelSequence /// diff --git a/src/lib/dns/name.cc b/src/lib/dns/name.cc index 5630435d0a..9eb6e9249f 100644 --- a/src/lib/dns/name.cc +++ b/src/lib/dns/name.cc @@ -427,7 +427,15 @@ Name::toWire(AbstractMessageRenderer& renderer) const { } std::string -Name::toText(bool omit_final_dot) const { +Name::toText(bool omit_final_dot, + unsigned int first_label, + unsigned int last_label) const { + if ((first_label > labelcount_) || + (last_label > labelcount_) || + (first_label > last_label)) { + isc_throw(BadValue, "Bad first label indices were passed"); + } + if (length_ == 1) { // // Special handling for the root label. We ignore omit_final_dot. @@ -438,7 +446,7 @@ Name::toText(bool omit_final_dot) const { NameString::const_iterator np = ndata_.begin(); NameString::const_iterator np_end = ndata_.end(); - unsigned int labels = labelcount_; // use for integrity check + unsigned int labels = last_label - first_label; // use for integrity check // init with an impossible value to catch error cases in the end: unsigned int count = MAX_LABELLEN + 1; @@ -447,6 +455,11 @@ Name::toText(bool omit_final_dot) const { std::string result; result.reserve(length_); + for (unsigned int i = 0; i < first_label; i++) { + count = *np++; + np += count; + } + while (np != np_end) { labels--; count = *np++; @@ -458,6 +471,11 @@ Name::toText(bool omit_final_dot) const { break; } + if (labels == 0) { + count = 0; + break; + } + if (count <= MAX_LABELLEN) { assert(np_end - np >= count); @@ -505,6 +523,11 @@ Name::toText(bool omit_final_dot) const { return (result); } +std::string +Name::toText(bool omit_final_dot) const { + return toText(omit_final_dot, 0, labelcount_); +} + NameComparisonResult Name::compare(const Name& other) const { // Determine the relative ordering under the DNSSEC order relation of diff --git a/src/lib/dns/name.h b/src/lib/dns/name.h index 41024fcaa3..e71359fdc0 100644 --- a/src/lib/dns/name.h +++ b/src/lib/dns/name.h @@ -359,6 +359,33 @@ public: /// \return a string representation of the <code>Name</code>. std::string toText(bool omit_final_dot = false) const; +private: + /// \brief Convert the Name to a string. + /// + /// This method returns a <code>std::string</code> object representing the + /// Name as a string. Unless <code>omit_final_dot</code> is + /// <code>true</code>, the returned string ends with a dot '.'; the default + /// is <code>false</code>. The default value of this parameter is + /// <code>true</code>; converted names will have a trailing dot by default. + /// + /// This function assumes the name is in proper uncompressed wire format. + /// If it finds an unexpected label character including compression pointer, + /// an exception of class \c BadLabelType will be thrown. + /// In addition, if resource allocation for the result string fails, a + /// corresponding standard exception will be thrown. + /// + /// This function only returns a string for the range of labels + /// between <code>first_label</code> and <code>last_label</code>. + // + /// \param omit_final_dot whether to omit the trailing dot in the output. + /// \param first_label the first label which should be contained in the result. + /// \param last_label the last label which should be contained in the result. + /// \return a string representation of the <code>Name</code>. + std::string toText(bool omit_final_dot, + unsigned int first_label, + unsigned int last_label) const; + +public: /// \brief Render the <code>Name</code> in the wire format with compression. /// /// This method dumps the Name in wire format with help of \c renderer, diff --git a/src/lib/dns/tests/labelsequence_unittest.cc b/src/lib/dns/tests/labelsequence_unittest.cc index 0e1fd5ee8c..711d988503 100644 --- a/src/lib/dns/tests/labelsequence_unittest.cc +++ b/src/lib/dns/tests/labelsequence_unittest.cc @@ -292,6 +292,27 @@ TEST_F(LabelSequenceTest, isAbsolute) { ASSERT_TRUE(ls3.isAbsolute()); } +TEST_F(LabelSequenceTest, toText) { + EXPECT_EQ("example.org.", ls1.toText()); + ls1.stripLeft(1); + EXPECT_EQ("org.", ls1.toText()); + ls1.stripLeft(1); + EXPECT_EQ(".", ls1.toText()); + + EXPECT_EQ("example.com.", ls2.toText()); + ls2.stripRight(1); + EXPECT_EQ("example", ls2.toText()); + ls2.stripRight(1); + EXPECT_EQ("", ls2.toText()); + + EXPECT_EQ("foo.example.org.bar.", ls8.toText()); + ls8.stripRight(2); + EXPECT_EQ("foo.example", ls8.toText()); + + EXPECT_EQ(".", ls7.toText()); + EXPECT_THROW(ls7.stripLeft(1), isc::OutOfRange); +} + // The following are test data used in the getHash test below. Normally // we use example/documentation domain names for testing, but in this case // we'd specifically like to use more realistic data, and are intentionally |