BIND 10 master, updated. c6603decaadcd33ccf9aee4a7b22447acec4b7f6 Merge branch 'trac2521'

BIND 10 source code commits bind10-changes at lists.isc.org
Wed May 8 15:40:32 UTC 2013


The branch, master has been updated
       via  c6603decaadcd33ccf9aee4a7b22447acec4b7f6 (commit)
       via  65b7adb8a1578ae6f070b9c877149d0db77aefda (commit)
       via  dac1394a30be534559eda0cfeaa140eace9000a6 (commit)
       via  885821d16691e4179678e4d7f61d550774c1a7a6 (commit)
       via  225a1e04ba13d2a48bbf3e1f958ce4e3f86aed49 (commit)
       via  caefbb6f9016955ad62391d799fd69886aa363b4 (commit)
       via  5045f86bbd1c7ffaf07c95f7c6ce4d64b1e1c467 (commit)
       via  94d255e2f177399d659e53ae06d622f2576b7e4c (commit)
       via  bec8813a793940089543c8875afc3ea475662459 (commit)
       via  e8655ab138c37f22582c7370677a4361cb6d6363 (commit)
       via  23db9e9d61274b5c8c4d23b493cbd582eb9eda4a (commit)
       via  2a6431ad41175316c82c7d13c0bffa0de9a44a7b (commit)
       via  1d3b43a5f11c82ea80c9c8469cb8aee4f504cb20 (commit)
       via  d24f908722f73071dd220b3457123d3e9dd2deae (commit)
       via  6b983412d569f2e7e81f6e6bebe37720f146d9b2 (commit)
       via  f3ca4f39256d94a48ed38f886b70d8195f89c83d (commit)
       via  b4093345f5b38af66fc7b2630baeaf843a817f74 (commit)
       via  4c8efe3ad82e6f62f663579c4e792f70db7012bc (commit)
       via  3bfd98d48a7b8e132931a950cf5d52ae1b324159 (commit)
       via  d06ff546486bc123c1fafbe8b20bb5e60557970c (commit)
       via  858d5facb7af996524fed919231d5ff55ad54aa4 (commit)
       via  2fdd3551e1012e61c414c475741f0013fce9e11e (commit)
       via  c9095ff3de68440efa427a536985bb01e0125504 (commit)
       via  870cc9bca34feab530b12cb870fd92f365513571 (commit)
       via  fdb992f0a2699cdad3bcaef79c2ca35f8e700c16 (commit)
       via  9ac31c2a7d7d2ee78ef2de4d56d3f57f6f45d75a (commit)
       via  5629c01345df4fd78a544169fac69e2afc9322a9 (commit)
      from  315d2846dec8b2f36df1aa8ed23feddfc621a356 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit c6603decaadcd33ccf9aee4a7b22447acec4b7f6
Merge: 315d284 65b7adb
Author: Paul Selkirk <pselkirk at isc.org>
Date:   Wed May 8 11:37:31 2013 -0400

    Merge branch 'trac2521'
    
    Conflicts:
    	src/lib/dns/gen-rdatacode.py.in

-----------------------------------------------------------------------

Summary of changes:
 src/lib/dns/gen-rdatacode.py.in           |    8 +-
 src/lib/dns/rdata/generic/opt_41.cc       |   19 ++-
 src/lib/dns/rdata/generic/rrsig_46.cc     |  142 ++++++++++++++----
 src/lib/dns/rdata/generic/rrsig_46.h      |   12 +-
 src/lib/dns/rdata/in_1/dhcid_49.cc        |   90 ++++++-----
 src/lib/dns/rdata/in_1/dhcid_49.h         |    5 +-
 src/lib/dns/tests/message_unittest.cc     |    4 +-
 src/lib/dns/tests/rdata_dhcid_unittest.cc |   93 +++++++++---
 src/lib/dns/tests/rdata_opt_unittest.cc   |    2 +-
 src/lib/dns/tests/rdata_rrsig_unittest.cc |  233 ++++++++++++++++++++++++++---
 src/lib/dns/tests/rrcollator_unittest.cc  |    6 +-
 src/lib/dns/tests/rrset_unittest.cc       |    4 +-
 12 files changed, 497 insertions(+), 121 deletions(-)

-----------------------------------------------------------------------
diff --git a/src/lib/dns/gen-rdatacode.py.in b/src/lib/dns/gen-rdatacode.py.in
index e265d56..a49f72f 100755
--- a/src/lib/dns/gen-rdatacode.py.in
+++ b/src/lib/dns/gen-rdatacode.py.in
@@ -1,6 +1,6 @@
 #!@PYTHON@
 
-# Copyright (C) 2010  Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2010-2013  Internet Systems Consortium, Inc. ("ISC")
 #
 # Permission to use, copy, modify, and/or distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
@@ -32,9 +32,11 @@ import sys
 #
 # Example:
 #     new_rdata_factory_users = [('a', 'in'), ('a', 'ch'), ('soa', 'generic')]
-new_rdata_factory_users = [('a', 'in'), ('aaaa', 'in'),
+new_rdata_factory_users = [('a', 'in'),
+                           ('aaaa', 'in'),
                            ('afsdb', 'generic'),
                            ('cname', 'generic'),
+                           ('dhcid', 'in'),
                            ('dlv', 'generic'),
                            ('dname', 'generic'),
                            ('dnskey', 'generic'),
@@ -46,7 +48,9 @@ new_rdata_factory_users = [('a', 'in'), ('aaaa', 'in'),
                            ('nsec', 'generic'),
                            ('nsec3', 'generic'),
                            ('nsec3param', 'generic'),
+                           ('opt', 'generic'),
                            ('ptr', 'generic'),
+                           ('rrsig', 'generic'),
                            ('soa', 'generic'),
                            ('spf', 'generic'),
                            ('srv', 'in'),
diff --git a/src/lib/dns/rdata/generic/opt_41.cc b/src/lib/dns/rdata/generic/opt_41.cc
index d64effb..136bdf9 100644
--- a/src/lib/dns/rdata/generic/opt_41.cc
+++ b/src/lib/dns/rdata/generic/opt_41.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2010  Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2010-2013  Internet Systems Consortium, Inc. ("ISC")
 //
 // Permission to use, copy, modify, and/or distribute this software for any
 // purpose with or without fee is hereby granted, provided that the above
@@ -27,10 +27,26 @@ using namespace isc::util;
 // BEGIN_ISC_NAMESPACE
 // BEGIN_RDATA_NAMESPACE
 
+/// \brief Constructor from string.
+///
+/// This constructor cannot be used, and always throws an exception.
+///
+/// \throw InvalidRdataText OPT RR cannot be constructed from text.
 OPT::OPT(const std::string&) {
     isc_throw(InvalidRdataText, "OPT RR cannot be constructed from text");
 }
 
+/// \brief Constructor with a context of MasterLexer.
+///
+/// This constructor cannot be used, and always throws an exception.
+///
+/// \throw InvalidRdataText OPT RR cannot be constructed from text.
+OPT::OPT(MasterLexer&, const Name*,
+       MasterLoader::Options, MasterLoaderCallbacks&)
+{
+    isc_throw(InvalidRdataText, "OPT RR cannot be constructed from text");
+}
+
 OPT::OPT(InputBuffer& buffer, size_t rdata_len) {
     // setPosition() will throw against a short buffer anyway, but it's safer
     // to check it explicitly here.
@@ -48,6 +64,7 @@ OPT::OPT(const OPT&) : Rdata() {
 
 std::string
 OPT::toText() const {
+    // OPT records do not have a text format.
     return ("");
 }
 
diff --git a/src/lib/dns/rdata/generic/rrsig_46.cc b/src/lib/dns/rdata/generic/rrsig_46.cc
index e0137b9..8e826d7 100644
--- a/src/lib/dns/rdata/generic/rrsig_46.cc
+++ b/src/lib/dns/rdata/generic/rrsig_46.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2010  Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2010-2013  Internet Systems Consortium, Inc. ("ISC")
 //
 // Permission to use, copy, modify, and/or distribute this software for any
 // purpose with or without fee is hereby granted, provided that the above
@@ -26,9 +26,9 @@
 #include <dns/messagerenderer.h>
 #include <dns/name.h>
 #include <dns/rrtype.h>
-#include <dns/rrttl.h>
 #include <dns/rdata.h>
 #include <dns/rdataclass.h>
+#include <dns/rdata/generic/detail/lexer_util.h>
 
 #include <stdio.h>
 #include <time.h>
@@ -36,6 +36,7 @@
 using namespace std;
 using namespace isc::util;
 using namespace isc::util::encode;
+using isc::dns::rdata::generic::detail::createNameFromLexer;
 
 // BEGIN_ISC_NAMESPACE
 // BEGIN_RDATA_NAMESPACE
@@ -52,8 +53,8 @@ const size_t RRSIG_MINIMUM_LEN = 2 * sizeof(uint8_t) + 2 * sizeof(uint16_t) +
 struct RRSIGImpl {
     // straightforward representation of RRSIG RDATA fields
     RRSIGImpl(const RRType& covered, uint8_t algorithm, uint8_t labels,
-              uint32_t originalttl, uint32_t timeexpire, uint32_t timeinception,
-              uint16_t tag, const Name& signer,
+              uint32_t originalttl, uint32_t timeexpire,
+              uint32_t timeinception, uint16_t tag, const Name& signer,
               const vector<uint8_t>& signature) :
         covered_(covered), algorithm_(algorithm), labels_(labels),
         originalttl_(originalttl), timeexpire_(timeexpire),
@@ -72,38 +73,125 @@ struct RRSIGImpl {
     const vector<uint8_t> signature_;
 };
 
-RRSIG::RRSIG(const std::string& rrsig_str) :
-    impl_(NULL)
-{
-    istringstream iss(rrsig_str);
-    string covered_txt, signer_txt, expire_txt, inception_txt;
-    unsigned int algorithm, labels;
-    uint32_t originalttl;
-    uint16_t tag;
-    stringbuf signaturebuf;
-
-    iss >> covered_txt >> algorithm >> labels >> originalttl
-        >> expire_txt >> inception_txt >> tag >> signer_txt
-        >> &signaturebuf;
-    if (iss.bad() || iss.fail()) {
-        isc_throw(InvalidRdataText, "Invalid RRSIG text");
-    }
+// helper function for string and lexer constructors
+RRSIGImpl*
+RRSIG::constructFromLexer(MasterLexer& lexer, const Name* origin) {
+    const RRType covered(lexer.getNextToken(MasterToken::STRING).getString());
+    const uint32_t algorithm =
+        lexer.getNextToken(MasterToken::NUMBER).getNumber();
     if (algorithm > 0xff) {
         isc_throw(InvalidRdataText, "RRSIG algorithm out of range");
     }
+    const uint32_t labels =
+        lexer.getNextToken(MasterToken::NUMBER).getNumber();
     if (labels > 0xff) {
         isc_throw(InvalidRdataText, "RRSIG labels out of range");
     }
-
-    const uint32_t timeexpire = timeFromText32(expire_txt);
-    const uint32_t timeinception = timeFromText32(inception_txt);
+    const uint32_t originalttl =
+        lexer.getNextToken(MasterToken::NUMBER).getNumber();
+    const uint32_t timeexpire =
+        timeFromText32(lexer.getNextToken(MasterToken::STRING).getString());
+    const uint32_t timeinception =
+        timeFromText32(lexer.getNextToken(MasterToken::STRING).getString());
+    const uint32_t tag =
+        lexer.getNextToken(MasterToken::NUMBER).getNumber();
+    if (tag > 0xffff) {
+        isc_throw(InvalidRdataText, "RRSIG key tag out of range");
+    }
+    const Name& signer = createNameFromLexer(lexer, origin);
+
+    string signature_txt;
+    string signature_part;
+    // Whitespace is allowed within base64 text, so read to the end of input.
+    while (true) {
+        const MasterToken& token =
+            lexer.getNextToken(MasterToken::STRING, true);
+        if ((token.getType() == MasterToken::END_OF_FILE) ||
+            (token.getType() == MasterToken::END_OF_LINE)) {
+            break;
+        }
+        token.getString(signature_part);
+        signature_txt.append(signature_part);
+    }
+    lexer.ungetToken();
 
     vector<uint8_t> signature;
-    decodeBase64(signaturebuf.str(), signature);
+    // missing signature is okay
+    if (signature_txt.size() > 0) {
+        decodeBase64(signature_txt, signature);
+    }
 
-    impl_ = new RRSIGImpl(RRType(covered_txt), algorithm, labels,
-                          originalttl, timeexpire, timeinception, tag,
-                          Name(signer_txt), signature);
+    return (new RRSIGImpl(covered, algorithm, labels,
+                          originalttl, timeexpire, timeinception,
+                          static_cast<uint16_t>(tag), signer, signature));
+}
+
+/// \brief Constructor from string.
+///
+/// The given string must represent a valid RRSIG RDATA.  There can be extra
+/// space characters at the beginning or end of the text (which are simply
+/// ignored), but other extra text, including a new line, will make the
+/// construction fail with an exception.
+///
+/// The Signer's Name must be absolute since there's no parameter that
+/// specifies the origin name; if this is not absolute, \c MissingNameOrigin
+/// exception will be thrown.  This must not be represented as a quoted
+/// string.
+///
+/// See the construction that takes \c MasterLexer for other fields.
+///
+/// \throw Others Exception from the Name constructor.
+/// \throw InvalidRdataText Other general syntax errors.
+RRSIG::RRSIG(const std::string& rrsig_str) :
+    impl_(NULL)
+{
+    // We use auto_ptr here because if there is an exception in this
+    // constructor, the destructor is not called and there could be a
+    // leak of the RRSIGImpl that constructFromLexer() returns.
+    std::auto_ptr<RRSIGImpl> impl_ptr(NULL);
+
+    try {
+        std::istringstream iss(rrsig_str);
+        MasterLexer lexer;
+        lexer.pushSource(iss);
+
+        impl_ptr.reset(constructFromLexer(lexer, NULL));
+
+        if (lexer.getNextToken().getType() != MasterToken::END_OF_FILE) {
+            isc_throw(InvalidRdataText, "extra input text for RRSIG: "
+                      << rrsig_str);
+        }
+    } catch (const MasterLexer::LexerError& ex) {
+        isc_throw(InvalidRdataText, "Failed to construct RRSIG from '" <<
+                  rrsig_str << "': " << ex.what());
+    }
+
+    impl_ = impl_ptr.release();
+}
+
+/// \brief Constructor with a context of MasterLexer.
+///
+/// The \c lexer should point to the beginning of valid textual representation
+/// of an RRSIG RDATA.  The Signer's Name fields can be non absolute if \c
+/// origin is non NULL, in which case \c origin is used to make it absolute.
+/// This must not be represented as a quoted string.
+///
+/// The Original TTL field is a valid decimal representation of an unsigned
+/// 32-bit integer. Note that alternate textual representations of \c RRTTL,
+/// such as "1H" for 3600 seconds, are not allowed here.
+///
+/// \throw MasterLexer::LexerError General parsing error such as missing field.
+/// \throw Other Exceptions from the Name constructor if
+/// construction of textual fields as these objects fail.
+///
+/// \param lexer A \c MasterLexer object parsing a master file for the
+/// RDATA to be created
+/// \param origin If non NULL, specifies the origin of Signer's Name when
+/// it is non absolute.
+RRSIG::RRSIG(MasterLexer& lexer, const Name* origin,
+             MasterLoader::Options, MasterLoaderCallbacks&) :
+    impl_(constructFromLexer(lexer, origin))
+{
 }
 
 RRSIG::RRSIG(InputBuffer& buffer, size_t rdata_len) {
diff --git a/src/lib/dns/rdata/generic/rrsig_46.h b/src/lib/dns/rdata/generic/rrsig_46.h
index b32c17f..de72f64 100644
--- a/src/lib/dns/rdata/generic/rrsig_46.h
+++ b/src/lib/dns/rdata/generic/rrsig_46.h
@@ -1,4 +1,4 @@
-// Copyright (C) 2010  Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2010-2013  Internet Systems Consortium, Inc. ("ISC")
 //
 // Permission to use, copy, modify, and/or distribute this software for any
 // purpose with or without fee is hereby granted, provided that the above
@@ -18,7 +18,6 @@
 
 #include <dns/name.h>
 #include <dns/rrtype.h>
-#include <dns/rrttl.h>
 #include <dns/rdata.h>
 
 // BEGIN_HEADER_GUARD
@@ -32,6 +31,12 @@
 
 struct RRSIGImpl;
 
+/// \brief \c rdata::RRSIG class represents the RRSIG RDATA as defined %in
+/// RFC4034.
+///
+/// This class implements the basic interfaces inherited from the abstract
+/// \c rdata::Rdata class, and provides trivial accessors specific to the
+/// RRSIG RDATA.
 class RRSIG : public Rdata {
 public:
     // BEGIN_COMMON_MEMBERS
@@ -42,6 +47,9 @@ public:
     // specialized methods
     const RRType& typeCovered() const;
 private:
+    // helper function for string and lexer constructors
+    RRSIGImpl* constructFromLexer(MasterLexer& lexer, const Name* origin);
+
     RRSIGImpl* impl_;
 };
 
diff --git a/src/lib/dns/rdata/in_1/dhcid_49.cc b/src/lib/dns/rdata/in_1/dhcid_49.cc
index 7745161..184866c 100644
--- a/src/lib/dns/rdata/in_1/dhcid_49.cc
+++ b/src/lib/dns/rdata/in_1/dhcid_49.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2011  Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2011-2013  Internet Systems Consortium, Inc. ("ISC")
 //
 // Permission to use, copy, modify, and/or distribute this software for any
 // purpose with or without fee is hereby granted, provided that the above
@@ -15,8 +15,6 @@
 #include <stdint.h>
 #include <string.h>
 
-#include <string>
-
 #include <exceptions/exceptions.h>
 
 #include <util/buffer.h>
@@ -28,53 +26,77 @@
 
 using namespace std;
 using namespace isc::util;
+using namespace isc::util::encode;
 
 // BEGIN_ISC_NAMESPACE
 // BEGIN_RDATA_NAMESPACE
 
+void
+DHCID::constructFromLexer(MasterLexer& lexer) {
+    string digest_txt = lexer.getNextToken(MasterToken::STRING).getString();
+
+    // Whitespace is allowed within base64 text, so read to the end of input.
+    string digest_part;
+    while (true) {
+        const MasterToken& token =
+            lexer.getNextToken(MasterToken::STRING, true);
+        if ((token.getType() == MasterToken::END_OF_FILE) ||
+            (token.getType() == MasterToken::END_OF_LINE)) {
+            break;
+        }
+        token.getString(digest_part);
+        digest_txt.append(digest_part);
+    }
+    lexer.ungetToken();
+
+    decodeBase64(digest_txt, digest_);
+}
+
 /// \brief Constructor from string.
 ///
 /// \param dhcid_str A base-64 representation of the DHCID binary data.
-/// The data is considered to be opaque, but a sanity check is performed.
-///
-/// <b>Exceptions</b>
 ///
-/// \c dhcid_str must be a valid  BASE-64 string, otherwise an exception
-/// of class \c isc::BadValue will be thrown;
-/// the binary data should consist of at leat of 3 octets as per RFC4701:
-///           < 2 octets >    Identifier type code
-///           < 1 octet >     Digest type code
-///           < n octets >    Digest (length depends on digest type)
-/// If the data is less than 3 octets (i.e. it cannot contain id type code and
-/// digest type code), an exception of class \c InvalidRdataLength is thrown.
+/// \throw InvalidRdataText if the string could not be parsed correctly.
 DHCID::DHCID(const std::string& dhcid_str) {
-    istringstream iss(dhcid_str);
-    stringbuf digestbuf;
-
-    iss >> &digestbuf;
-    isc::util::encode::decodeBase64(digestbuf.str(), digest_);
-
-    // RFC4701 states DNS software should consider the RDATA section to
-    // be opaque, but there must be at least three bytes in the data:
-    // < 2 octets >    Identifier type code
-    // < 1 octet >     Digest type code
-    if (digest_.size() < 3) {
-        isc_throw(InvalidRdataLength, "DHCID length " << digest_.size() <<
-                  " too short, need at least 3 bytes");
+    try {
+        std::istringstream iss(dhcid_str);
+        MasterLexer lexer;
+        lexer.pushSource(iss);
+
+        constructFromLexer(lexer);
+
+        if (lexer.getNextToken().getType() != MasterToken::END_OF_FILE) {
+            isc_throw(InvalidRdataText, "extra input text for DHCID: "
+                      << dhcid_str);
+        }
+    } catch (const MasterLexer::LexerError& ex) {
+        isc_throw(InvalidRdataText, "Failed to construct DHCID from '" <<
+                  dhcid_str << "': " << ex.what());
     }
 }
 
+/// \brief Constructor with a context of MasterLexer.
+///
+/// The \c lexer should point to the beginning of valid textual representation
+/// of a DHCID RDATA.
+///
+/// \throw BadValue if the text is not valid base-64.
+/// \throw MasterLexer::LexerError General parsing error such as missing field.
+///
+/// \param lexer A \c MasterLexer object parsing a master file for the
+/// RDATA to be created
+DHCID::DHCID(MasterLexer& lexer, const Name*,
+             MasterLoader::Options, MasterLoaderCallbacks&) {
+    constructFromLexer(lexer);
+}
+
 /// \brief Constructor from wire-format data.
 ///
 /// \param buffer A buffer storing the wire format data.
 /// \param rdata_len The length of the RDATA in bytes
-///
-/// <b>Exceptions</b>
-/// \c InvalidRdataLength is thrown if \c rdata_len is than minimum of 3 octets
 DHCID::DHCID(InputBuffer& buffer, size_t rdata_len) {
-    if (rdata_len < 3) {
-        isc_throw(InvalidRdataLength, "DHCID length " << rdata_len <<
-                  " too short, need at least 3 bytes");
+    if (rdata_len == 0) {
+        isc_throw(InvalidRdataLength, "Missing DHCID rdata");
     }
 
     digest_.resize(rdata_len);
@@ -112,7 +134,7 @@ DHCID::toWire(AbstractMessageRenderer& renderer) const {
 /// \return A string representation of \c DHCID.
 string
 DHCID::toText() const {
-    return (isc::util::encode::encodeBase64(digest_));
+    return (encodeBase64(digest_));
 }
 
 /// \brief Compare two instances of \c DHCID RDATA.
diff --git a/src/lib/dns/rdata/in_1/dhcid_49.h b/src/lib/dns/rdata/in_1/dhcid_49.h
index 90f5fab..81041b0 100644
--- a/src/lib/dns/rdata/in_1/dhcid_49.h
+++ b/src/lib/dns/rdata/in_1/dhcid_49.h
@@ -1,4 +1,4 @@
-// Copyright (C) 2011  Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2011-2013  Internet Systems Consortium, Inc. ("ISC")
 //
 // Permission to use, copy, modify, and/or distribute this software for any
 // purpose with or without fee is hereby granted, provided that the above
@@ -43,6 +43,9 @@ public:
     const std::vector<uint8_t>& getDigest() const;
 
 private:
+    // helper for string and lexer constructors
+    void constructFromLexer(MasterLexer& lexer);
+
     /// \brief Private data representation
     ///
     /// Opaque data at least 3 octets long as per RFC4701.
diff --git a/src/lib/dns/tests/message_unittest.cc b/src/lib/dns/tests/message_unittest.cc
index 835aa48..8aaebaa 100644
--- a/src/lib/dns/tests/message_unittest.cc
+++ b/src/lib/dns/tests/message_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2010  Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2010-2013  Internet Systems Consortium, Inc. ("ISC")
 //
 // Permission to use, copy, modify, and/or distribute this software for any
 // purpose with or without fee is hereby granted, provided that the above
@@ -98,7 +98,7 @@ protected:
         rrset_rrsig = RRsetPtr(new RRset(test_name, RRClass::IN(),
                                         RRType::RRSIG(), RRTTL(3600)));
         rrset_rrsig->addRdata(generic::RRSIG("AAAA 5 3 7200 20100322084538 "
-                                             "20100220084538 1 example.com "
+                                             "20100220084538 1 example.com. "
                                              "FAKEFAKEFAKEFAKE"));
         rrset_aaaa->addRRsig(rrset_rrsig);
     }
diff --git a/src/lib/dns/tests/rdata_dhcid_unittest.cc b/src/lib/dns/tests/rdata_dhcid_unittest.cc
index 8d56c0e..77baccd 100644
--- a/src/lib/dns/tests/rdata_dhcid_unittest.cc
+++ b/src/lib/dns/tests/rdata_dhcid_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2011  Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2011-2013  Internet Systems Consortium, Inc. ("ISC")
 //
 // Permission to use, copy, modify, and/or distribute this software for any
 // purpose with or without fee is hereby granted, provided that the above
@@ -12,6 +12,8 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
+#include <exceptions/exceptions.h>
+
 #include <util/buffer.h>
 #include <dns/rdataclass.h>
 #include <util/encode/base64.h>
@@ -23,6 +25,7 @@
 
 using isc::UnitTestUtil;
 using namespace std;
+using namespace isc;
 using namespace isc::dns;
 using namespace isc::util;
 using namespace isc::util::encode;
@@ -30,25 +33,69 @@ using namespace isc::dns::rdata;
 
 namespace {
 
-const string string_dhcid(
-                   "0LIg0LvQtdGB0YMg0YDQvtC00LjQu9Cw0YHRjCDRkdC70L7Rh9C60LA=");
-
-const in::DHCID rdata_dhcid(string_dhcid);
-
 class Rdata_DHCID_Test : public RdataTest {
+protected:
+    Rdata_DHCID_Test() :
+        dhcid_txt("0LIg0LvQtdGB0YMg0YDQvtC00LjQu9Cw0YHRjCDRkdC70L7Rh9C60LA="),
+        rdata_dhcid(dhcid_txt)
+    {}
+
+    void checkFromText_None(const string& rdata_str) {
+        checkFromText<in::DHCID, isc::Exception, isc::Exception>(
+            rdata_str, rdata_dhcid, false, false);
+    }
+
+    void checkFromText_BadValue(const string& rdata_str) {
+        checkFromText<in::DHCID, BadValue, BadValue>(
+            rdata_str, rdata_dhcid, true, true);
+    }
+
+    void checkFromText_LexerError(const string& rdata_str) {
+        checkFromText
+            <in::DHCID, InvalidRdataText, MasterLexer::LexerError>(
+                rdata_str, rdata_dhcid, true, true);
+    }
+
+    void checkFromText_BadString(const string& rdata_str) {
+        checkFromText
+            <in::DHCID, InvalidRdataText, isc::Exception>(
+                rdata_str, rdata_dhcid, true, false);
+    }
+
+    const string dhcid_txt;
+    const in::DHCID rdata_dhcid;
 };
 
-TEST_F(Rdata_DHCID_Test, createFromString) {
-    const in::DHCID rdata_dhcid2(string_dhcid);
-    EXPECT_EQ(0, rdata_dhcid2.compare(rdata_dhcid));
-}
+TEST_F(Rdata_DHCID_Test, fromText) {
+    EXPECT_EQ(dhcid_txt, rdata_dhcid.toText());
+
+    // Space in digest data is OK
+    checkFromText_None(
+            "0LIg0LvQtdGB0YMg 0YDQvtC00LjQu9Cw 0YHRjCDRkdC70L7R h9C60LA=");
+
+    // Multi-line digest data is OK, if enclosed in parentheses
+    checkFromText_None(
+            "( 0LIg0LvQtdGB0YMg0YDQvtC00LjQu9Cw\n0YHRjCDRkdC70L7R h9C60LA= )");
 
-TEST_F(Rdata_DHCID_Test, badBase64) {
-    EXPECT_THROW(const in::DHCID rdata_dhcid_bad("00"), isc::BadValue);
+    // Trailing garbage. This should cause only the string constructor
+    // to fail, but the lexer constructor must be able to continue
+    // parsing from it.
+    checkFromText_BadString(
+            "0LIg0LvQtdGB0YMg0YDQvtC00LjQu9Cw0YHRjCDRkdC70L7Rh9C60LA="
+            " ; comment\n"
+            "AAIBY2/AuCccgoJbsaxcQc9TUapptP69lOjxfNuVAA2kjEA=");
 }
 
-TEST_F(Rdata_DHCID_Test, badLength) {
-    EXPECT_THROW(const in::DHCID rdata_dhcid_bad("MDA="), InvalidRdataLength);
+TEST_F(Rdata_DHCID_Test, badText) {
+    // missing digest data
+    checkFromText_LexerError("");
+
+    // invalid base64
+    checkFromText_BadValue("EEeeeeeeEEEeeeeeeGaaahAAAAAAAAHHHHHHHHHHH!=");
+
+    // unterminated multi-line base64
+    checkFromText_LexerError(
+            "( 0LIg0LvQtdGB0YMg0YDQvtC00LjQu9Cw\n0YHRjCDRkdC70L7R h9C60LA=");
 }
 
 TEST_F(Rdata_DHCID_Test, copy) {
@@ -60,17 +107,17 @@ TEST_F(Rdata_DHCID_Test, createFromWire) {
     EXPECT_EQ(0, rdata_dhcid.compare(
                   *rdataFactoryFromFile(RRType("DHCID"), RRClass("IN"),
                                         "rdata_dhcid_fromWire")));
+
+    InputBuffer buffer(NULL, 0);
+    EXPECT_THROW(in::DHCID(buffer, 0), InvalidRdataLength);
+
     // TBD: more tests
 }
 
 TEST_F(Rdata_DHCID_Test, createFromLexer) {
     EXPECT_EQ(0, rdata_dhcid.compare(
         *test::createRdataUsingLexer(RRType::DHCID(), RRClass::IN(),
-                                     string_dhcid)));
-
-    // Exceptions cause NULL to be returned.
-    EXPECT_FALSE(test::createRdataUsingLexer(RRType::DHCID(), RRClass::IN(),
-                                             "00"));
+                                     dhcid_txt)));
 }
 
 TEST_F(Rdata_DHCID_Test, toWireRenderer) {
@@ -92,13 +139,13 @@ TEST_F(Rdata_DHCID_Test, toWireBuffer) {
 }
 
 TEST_F(Rdata_DHCID_Test, toText) {
-    EXPECT_EQ(string_dhcid, rdata_dhcid.toText());
+    EXPECT_EQ(dhcid_txt, rdata_dhcid.toText());
 }
 
 TEST_F(Rdata_DHCID_Test, getDHCIDDigest) {
-    const string string_dhcid1(encodeBase64(rdata_dhcid.getDigest()));
+    const string dhcid_txt1(encodeBase64(rdata_dhcid.getDigest()));
 
-    EXPECT_EQ(string_dhcid, string_dhcid1);
+    EXPECT_EQ(dhcid_txt, dhcid_txt1);
 }
 
 TEST_F(Rdata_DHCID_Test, compare) {
@@ -117,6 +164,6 @@ TEST_F(Rdata_DHCID_Test, compare) {
     EXPECT_GT(rdata_dhcid3.compare(rdata_dhcid2), 0);
 
     // comparison attempt between incompatible RR types should be rejected
-    EXPECT_THROW(rdata_dhcid.compare(*rdata_nomatch), bad_cast); 
+    EXPECT_THROW(rdata_dhcid.compare(*rdata_nomatch), bad_cast);
 }
 }
diff --git a/src/lib/dns/tests/rdata_opt_unittest.cc b/src/lib/dns/tests/rdata_opt_unittest.cc
index 5699259..20ccfe4 100644
--- a/src/lib/dns/tests/rdata_opt_unittest.cc
+++ b/src/lib/dns/tests/rdata_opt_unittest.cc
@@ -84,6 +84,6 @@ TEST_F(Rdata_OPT_Test, compare) {
                                         "rdata_opt_fromWire", 2)));
 
     // comparison attempt between incompatible RR types should be rejected
-    EXPECT_THROW(rdata_opt.compare(*RdataTest::rdata_nomatch), bad_cast); 
+    EXPECT_THROW(rdata_opt.compare(*RdataTest::rdata_nomatch), bad_cast);
 }
 }
diff --git a/src/lib/dns/tests/rdata_rrsig_unittest.cc b/src/lib/dns/tests/rdata_rrsig_unittest.cc
index d758ff3..2d075ec 100644
--- a/src/lib/dns/tests/rdata_rrsig_unittest.cc
+++ b/src/lib/dns/tests/rdata_rrsig_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2010  Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2010-2013  Internet Systems Consortium, Inc. ("ISC")
 //
 // Permission to use, copy, modify, and/or distribute this software for any
 // purpose with or without fee is hereby granted, provided that the above
@@ -36,7 +36,7 @@ using namespace isc::dns::rdata;
 
 namespace {
 class Rdata_RRSIG_Test : public RdataTest {
-public:
+protected:
     Rdata_RRSIG_Test() :
         rrsig_txt("A 5 4 43200 20100223214617 20100222214617 8496 isc.org. "
                   "evxhlGx13mpKLVkKsjpGzycS5twtIoxOmlN14w9t5AgzGBmz"
@@ -46,6 +46,49 @@ public:
         rdata_rrsig(rrsig_txt)
     {}
 
+    void checkFromText_None(const string& rdata_str) {
+        checkFromText<generic::RRSIG, isc::Exception, isc::Exception>(
+            rdata_str, rdata_rrsig, false, false);
+    }
+
+    void checkFromText_InvalidText(const string& rdata_str) {
+        checkFromText<generic::RRSIG, InvalidRdataText, InvalidRdataText>(
+            rdata_str, rdata_rrsig, true, true);
+    }
+
+    void checkFromText_InvalidType(const string& rdata_str) {
+        checkFromText<generic::RRSIG, InvalidRRType, InvalidRRType>(
+            rdata_str, rdata_rrsig, true, true);
+    }
+
+    void checkFromText_InvalidTime(const string& rdata_str) {
+        checkFromText<generic::RRSIG, InvalidTime, InvalidTime>(
+            rdata_str, rdata_rrsig, true, true);
+    }
+
+    void checkFromText_BadValue(const string& rdata_str) {
+        checkFromText<generic::RRSIG, BadValue, BadValue>(
+            rdata_str, rdata_rrsig, true, true);
+    }
+
+    void checkFromText_LexerError(const string& rdata_str) {
+        checkFromText
+            <generic::RRSIG, InvalidRdataText, MasterLexer::LexerError>(
+                rdata_str, rdata_rrsig, true, true);
+    }
+
+    void checkFromText_MissingOrigin(const string& rdata_str) {
+        checkFromText
+            <generic::RRSIG, MissingNameOrigin, MissingNameOrigin>(
+                rdata_str, rdata_rrsig, true, true);
+    }
+
+    void checkFromText_BadString(const string& rdata_str) {
+        checkFromText
+            <generic::RRSIG, InvalidRdataText, isc::Exception>(
+                rdata_str, rdata_rrsig, true, false);
+    }
+
     const string rrsig_txt;
     const generic::RRSIG rdata_rrsig;
 };
@@ -53,52 +96,196 @@ public:
 TEST_F(Rdata_RRSIG_Test, fromText) {
     EXPECT_EQ(rrsig_txt, rdata_rrsig.toText());
     EXPECT_EQ(isc::dns::RRType::A(), rdata_rrsig.typeCovered());
+
+    // Missing signature is OK
+    EXPECT_NO_THROW(const generic::RRSIG sig(
+              "A 5 4 43200 20100223214617 20100222214617 8496 isc.org."));
+
+    // Space in signature data is OK
+    checkFromText_None(
+              "A 5 4 43200 20100223214617 20100222214617 8496 isc.org. "
+              "evxhlGx13mpKLVkKsjpGzycS5twtIoxOmlN14w9t5AgzGBmz "
+              "diGdLIrFabqr72af2rUq+UDBKMWXujwZTZUTws32sVldDPk/ "
+              "NbuacJM25fQXfv5mO3Af7TOoow3AjMaVG9icjCW0V55WcWQU "
+              "f49t+sXKPzbipN9g+s1ZPiIyofc=");
+
+    // Multi-line signature data is OK, if enclosed in parentheses
+    checkFromText_None(
+              "A 5 4 43200 20100223214617 20100222214617 8496 isc.org. "
+              "( evxhlGx13mpKLVkKsjpGzycS5twtIoxOmlN14w9t5AgzGBmz\n"
+              "diGdLIrFabqr72af2rUq+UDBKMWXujwZTZUTws32sVldDPk/\n"
+              "NbuacJM25fQXfv5mO3Af7TOoow3AjMaVG9icjCW0V55WcWQU\n"
+              "f49t+sXKPzbipN9g+s1ZPiIyofc= )");
+
+    // Trailing garbage. This should cause only the string constructor
+    // to fail, but the lexer constructor must be able to continue
+    // parsing from it.
+    checkFromText_BadString(
+              "A 5 4 43200 20100223214617 20100222214617 8496 isc.org. "
+              "evxhlGx13mpKLVkKsjpGzycS5twtIoxOmlN14w9t5AgzGBmz"
+              "diGdLIrFabqr72af2rUq+UDBKMWXujwZTZUTws32sVldDPk/"
+              "NbuacJM25fQXfv5mO3Af7TOoow3AjMaVG9icjCW0V55WcWQU"
+              "f49t+sXKPzbipN9g+s1ZPiIyofc= ; comment\n"
+              "A 5 4 43200 20100223214617 20100222214617 8496 isc.org. "
+              "evxhlGx13mpKLVkKsjpGzycS5twtIoxOmlN14w9t5AgzGBmz"
+              "diGdLIrFabqr72af2rUq+UDBKMWXujwZTZUTws32sVldDPk/"
+              "NbuacJM25fQXfv5mO3Af7TOoow3AjMaVG9icjCW0V55WcWQU"
+              "f49t+sXKPzbipN9g+s1ZPiIyofc=");
+}
+
+TEST_F(Rdata_RRSIG_Test, badText_missingFields) {
+    checkFromText_LexerError("A");
+    checkFromText_LexerError("A 5");
+    checkFromText_LexerError("A 5 4");
+    checkFromText_LexerError("A 5 4 43200");
+    checkFromText_LexerError("A 5 4 43200 20100223214617");
+    checkFromText_LexerError("A 5 4 43200 20100223214617 20100222214617");
+    checkFromText_LexerError("A 5 4 43200 20100223214617 20100222214617 "
+                              "8496");
+}
+
+TEST_F(Rdata_RRSIG_Test, badText_coveredType) {
+    checkFromText_InvalidType("SPORK");
+}
+
+TEST_F(Rdata_RRSIG_Test, badText_algorithm) {
+    checkFromText_InvalidText(
+                     "A 555 4 43200 "
+                     "20100223214617 20100222214617 8496 isc.org. "
+                     "evxhlGx13mpKLVkKsjpGzycS5twtIoxOmlN14w9t5AgzGBmz"
+                     "diGdLIrFabqr72af2rUq+UDBKMWXujwZTZUTws32sVldDPk/"
+                     "NbuacJM25fQXfv5mO3Af7TOoow3AjMaVG9icjCW0V55WcWQU"
+                     "f49t+sXKPzbipN9g+s1ZPiIyofc=");
+    checkFromText_LexerError(
+                     "A FIVE 4 43200 "
+                     "20100223214617 20100222214617 8496 isc.org. "
+                     "evxhlGx13mpKLVkKsjpGzycS5twtIoxOmlN14w9t5AgzGBmz"
+                     "diGdLIrFabqr72af2rUq+UDBKMWXujwZTZUTws32sVldDPk/"
+                     "NbuacJM25fQXfv5mO3Af7TOoow3AjMaVG9icjCW0V55WcWQU"
+                     "f49t+sXKPzbipN9g+s1ZPiIyofc=");
 }
 
-TEST_F(Rdata_RRSIG_Test, badText) {
-    EXPECT_THROW(const generic::RRSIG sig("SPORK"), InvalidRdataText);
-    EXPECT_THROW(const generic::RRSIG sig("A 555 4 43200 "
+TEST_F(Rdata_RRSIG_Test, badText_labels) {
+    checkFromText_InvalidText(
+                     "A 5 4444 43200 "
                      "20100223214617 20100222214617 8496 isc.org. "
                      "evxhlGx13mpKLVkKsjpGzycS5twtIoxOmlN14w9t5AgzGBmz"
                      "diGdLIrFabqr72af2rUq+UDBKMWXujwZTZUTws32sVldDPk/"
                      "NbuacJM25fQXfv5mO3Af7TOoow3AjMaVG9icjCW0V55WcWQU"
-                     "f49t+sXKPzbipN9g+s1ZPiIyofc="), InvalidRdataText);
-    EXPECT_THROW(const generic::RRSIG sig("A 5 4444 43200 "
+                     "f49t+sXKPzbipN9g+s1ZPiIyofc=");
+    checkFromText_LexerError(
+                     "A 5 FOUR 43200 "
                      "20100223214617 20100222214617 8496 isc.org. "
                      "evxhlGx13mpKLVkKsjpGzycS5twtIoxOmlN14w9t5AgzGBmz"
                      "diGdLIrFabqr72af2rUq+UDBKMWXujwZTZUTws32sVldDPk/"
                      "NbuacJM25fQXfv5mO3Af7TOoow3AjMaVG9icjCW0V55WcWQU"
-                     "f49t+sXKPzbipN9g+s1ZPiIyofc="), InvalidRdataText);
-    EXPECT_THROW(const generic::RRSIG sig("A 5 4 999999999999 "
+                     "f49t+sXKPzbipN9g+s1ZPiIyofc=");
+}
+
+TEST_F(Rdata_RRSIG_Test, badText_ttl) {
+    checkFromText_LexerError(
+                     "A 5 4 999999999999 "
                      "20100223214617 20100222214617 8496 isc.org. "
                      "evxhlGx13mpKLVkKsjpGzycS5twtIoxOmlN14w9t5AgzGBmz"
                      "diGdLIrFabqr72af2rUq+UDBKMWXujwZTZUTws32sVldDPk/"
                      "NbuacJM25fQXfv5mO3Af7TOoow3AjMaVG9icjCW0V55WcWQU"
-                     "f49t+sXKPzbipN9g+s1ZPiIyofc="), InvalidRdataText);
-    EXPECT_THROW(const generic::RRSIG sig("A 5 4 43200 "
-                     "20100223 20100227 8496 isc.org. "
+                     "f49t+sXKPzbipN9g+s1ZPiIyofc=");
+    checkFromText_LexerError(
+                     "A 5 4 TTL "
+                     "20100223214617 20100222214617 8496 isc.org. "
                      "evxhlGx13mpKLVkKsjpGzycS5twtIoxOmlN14w9t5AgzGBmz"
                      "diGdLIrFabqr72af2rUq+UDBKMWXujwZTZUTws32sVldDPk/"
                      "NbuacJM25fQXfv5mO3Af7TOoow3AjMaVG9icjCW0V55WcWQU"
-                     "f49t+sXKPzbipN9g+s1ZPiIyofc="), InvalidTime);
-    EXPECT_THROW(const generic::RRSIG sig("A 5 4 43200 "
+                     "f49t+sXKPzbipN9g+s1ZPiIyofc=");
+
+    // alternate form of TTL is not okay
+    checkFromText_LexerError(
+              "A 5 4 12H 20100223214617 20100222214617 8496 isc.org. "
+              "evxhlGx13mpKLVkKsjpGzycS5twtIoxOmlN14w9t5AgzGBmz "
+              "diGdLIrFabqr72af2rUq+UDBKMWXujwZTZUTws32sVldDPk/ "
+              "NbuacJM25fQXfv5mO3Af7TOoow3AjMaVG9icjCW0V55WcWQU "
+              "f49t+sXKPzbipN9g+s1ZPiIyofc=");
+}
+
+TEST_F(Rdata_RRSIG_Test, badText_expiration) {
+    checkFromText_InvalidTime(
+                     "A 5 4 43200 "
+                     "201002232 20100222214617 8496 isc.org. "
+                     "evxhlGx13mpKLVkKsjpGzycS5twtIoxOmlN14w9t5AgzGBmz"
+                     "diGdLIrFabqr72af2rUq+UDBKMWXujwZTZUTws32sVldDPk/"
+                     "NbuacJM25fQXfv5mO3Af7TOoow3AjMaVG9icjCW0V55WcWQU"
+                     "f49t+sXKPzbipN9g+s1ZPiIyofc=");
+    checkFromText_InvalidTime(
+                     "A 5 4 43200 "
+                     "EXPIRATION 20100222214617 8496 isc.org. "
+                     "evxhlGx13mpKLVkKsjpGzycS5twtIoxOmlN14w9t5AgzGBmz"
+                     "diGdLIrFabqr72af2rUq+UDBKMWXujwZTZUTws32sVldDPk/"
+                     "NbuacJM25fQXfv5mO3Af7TOoow3AjMaVG9icjCW0V55WcWQU"
+                     "f49t+sXKPzbipN9g+s1ZPiIyofc=");
+}
+
+TEST_F(Rdata_RRSIG_Test, badText_inception) {
+    checkFromText_InvalidTime(
+                     "A 5 4 43200 "
+                     "20100223214617 20100227 8496 isc.org. "
+                     "evxhlGx13mpKLVkKsjpGzycS5twtIoxOmlN14w9t5AgzGBmz"
+                     "diGdLIrFabqr72af2rUq+UDBKMWXujwZTZUTws32sVldDPk/"
+                     "NbuacJM25fQXfv5mO3Af7TOoow3AjMaVG9icjCW0V55WcWQU"
+                     "f49t+sXKPzbipN9g+s1ZPiIyofc=");
+    checkFromText_InvalidTime(
+                     "A 5 4 43200 "
+                     "20100223214617 INCEPTION 8496 isc.org. "
+                     "evxhlGx13mpKLVkKsjpGzycS5twtIoxOmlN14w9t5AgzGBmz"
+                     "diGdLIrFabqr72af2rUq+UDBKMWXujwZTZUTws32sVldDPk/"
+                     "NbuacJM25fQXfv5mO3Af7TOoow3AjMaVG9icjCW0V55WcWQU"
+                     "f49t+sXKPzbipN9g+s1ZPiIyofc=");
+}
+
+TEST_F(Rdata_RRSIG_Test, badText_keytag) {
+    checkFromText_InvalidText(
+                     "A 5 4 43200 "
                      "20100223214617 20100222214617 999999 isc.org. "
                      "evxhlGx13mpKLVkKsjpGzycS5twtIoxOmlN14w9t5AgzGBmz"
                      "diGdLIrFabqr72af2rUq+UDBKMWXujwZTZUTws32sVldDPk/"
                      "NbuacJM25fQXfv5mO3Af7TOoow3AjMaVG9icjCW0V55WcWQU"
-                     "f49t+sXKPzbipN9g+s1ZPiIyofc="), InvalidRdataText);
-    EXPECT_THROW(const generic::RRSIG sig(
+                     "f49t+sXKPzbipN9g+s1ZPiIyofc=");
+    checkFromText_LexerError(
                      "A 5 4 43200 "
-                     "20100223214617 20100222214617 8496 isc.org. "
-                     "EEeeeeeeEEEeeeeeeGaaahAAAAAAAAHHHHHHHHHHH!="),
-                 BadValue);     // bad base64 input
+                     "20100223214617 20100222214617 TAG isc.org. "
+                     "evxhlGx13mpKLVkKsjpGzycS5twtIoxOmlN14w9t5AgzGBmz"
+                     "diGdLIrFabqr72af2rUq+UDBKMWXujwZTZUTws32sVldDPk/"
+                     "NbuacJM25fQXfv5mO3Af7TOoow3AjMaVG9icjCW0V55WcWQU"
+                     "f49t+sXKPzbipN9g+s1ZPiIyofc=");
+}
+
+TEST_F(Rdata_RRSIG_Test, badText_signer) {
+    checkFromText_MissingOrigin(
+                     "A 5 4 43200 "
+                     "20100223214617 20100222214617 8496 isc.org "
+                     "evxhlGx13mpKLVkKsjpGzycS5twtIoxOmlN14w9t5AgzGBmz"
+                     "diGdLIrFabqr72af2rUq+UDBKMWXujwZTZUTws32sVldDPk/"
+                     "NbuacJM25fQXfv5mO3Af7TOoow3AjMaVG9icjCW0V55WcWQU"
+                     "f49t+sXKPzbipN9g+s1ZPiIyofc=");
 }
 
-TEST_F(Rdata_RRSIG_Test, DISABLED_badText) {
-    // this currently fails
+TEST_F(Rdata_RRSIG_Test, badText_signature) {
+    checkFromText_BadValue(
+                     "A 5 4 43200 "
+                     "20100223214617 20100222214617 8496 isc.org. "
+                     "EEeeeeeeEEEeeeeeeGaaahAAAAAAAAHHHHHHHHHHH!=");
+
     // no space between the tag and signer
-    EXPECT_THROW(generic::RRSIG("A 5 4 43200 20100223214617 20100222214617 "
-                                "8496isc.org. ofc="), InvalidRdataText);
+    checkFromText_LexerError(
+                     "A 5 4 43200 20100223214617 20100222214617 "
+                     "8496isc.org. ofc=");
+
+    // unterminated multi-line base64
+    checkFromText_LexerError(
+              "A 5 4 43200 20100223214617 20100222214617 8496 isc.org. "
+              "( evxhlGx13mpKLVkKsjpGzycS5twtIoxOmlN14w9t5AgzGBmz\n"
+              "diGdLIrFabqr72af2rUq+UDBKMWXujwZTZUTws32sVldDPk/\n"
+              "NbuacJM25fQXfv5mO3Af7TOoow3AjMaVG9icjCW0V55WcWQU\n"
+              "f49t+sXKPzbipN9g+s1ZPiIyofc=");
 }
 
 TEST_F(Rdata_RRSIG_Test, createFromLexer) {
diff --git a/src/lib/dns/tests/rrcollator_unittest.cc b/src/lib/dns/tests/rrcollator_unittest.cc
index e66f87c..9123dc5 100644
--- a/src/lib/dns/tests/rrcollator_unittest.cc
+++ b/src/lib/dns/tests/rrcollator_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2012  Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2012-2013  Internet Systems Consortium, Inc. ("ISC")
 //
 // Permission to use, copy, modify, and/or distribute this software for any
 // purpose with or without fee is hereby granted, provided that the above
@@ -59,10 +59,10 @@ protected:
         txt_rdata_(createRdata(RRType::TXT(), rrclass_, "test")),
         sig_rdata1_(createRdata(RRType::RRSIG(), rrclass_,
                                 "A 5 3 3600 20000101000000 20000201000000 "
-                                "12345 example.com. FAKE\n")),
+                                "12345 example.com. FAKE")),
         sig_rdata2_(createRdata(RRType::RRSIG(), rrclass_,
                                 "NS 5 3 3600 20000101000000 20000201000000 "
-                                "12345 example.com. FAKE\n"))
+                                "12345 example.com. FAKE"))
     {}
 
     void checkRRset(const Name& expected_name, const RRClass& expected_class,
diff --git a/src/lib/dns/tests/rrset_unittest.cc b/src/lib/dns/tests/rrset_unittest.cc
index d16ce3c..a605caf 100644
--- a/src/lib/dns/tests/rrset_unittest.cc
+++ b/src/lib/dns/tests/rrset_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2010  Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2010-2013  Internet Systems Consortium, Inc. ("ISC")
 //
 // Permission to use, copy, modify, and/or distribute this software for any
 // purpose with or without fee is hereby granted, provided that the above
@@ -289,7 +289,7 @@ protected:
         rrset_rrsig = RRsetPtr(new RRset(test_name, RRClass::IN(),
                                          RRType::RRSIG(), RRTTL(3600)));
         rrset_rrsig->addRdata(generic::RRSIG("AAAA 5 3 7200 20100322084538 "
-                                             "20100220084538 1 example.com "
+                                             "20100220084538 1 example.com. "
                                              "FAKEFAKEFAKEFAKE"));
         rrset_aaaa->addRRsig(rrset_rrsig);
     }



More information about the bind10-changes mailing list