diff options
author | Paul Selkirk <pselkirk@isc.org> | 2013-05-05 01:25:30 +0200 |
---|---|---|
committer | Paul Selkirk <pselkirk@isc.org> | 2013-05-16 05:33:30 +0200 |
commit | 3d234878c77fab6f7bb172c5ef2bd21cde768a72 (patch) | |
tree | 5486453c9a671a7911dbde88829c7ef0def781c7 | |
parent | [master] Merge branch 'trac2909' (diff) | |
download | kea-3d234878c77fab6f7bb172c5ef2bd21cde768a72.tar.xz kea-3d234878c77fab6f7bb172c5ef2bd21cde768a72.zip |
[2522] add MasterLexer constructor for RP
-rw-r--r-- | src/lib/dns/rdata/generic/rp_17.cc | 71 | ||||
-rw-r--r-- | src/lib/dns/rdata/generic/rp_17.h | 5 | ||||
-rw-r--r-- | src/lib/dns/tests/rdata_rp_unittest.cc | 42 |
3 files changed, 90 insertions, 28 deletions
diff --git a/src/lib/dns/rdata/generic/rp_17.cc b/src/lib/dns/rdata/generic/rp_17.cc index 781b55d6bf..b6b47cc636 100644 --- a/src/lib/dns/rdata/generic/rp_17.cc +++ b/src/lib/dns/rdata/generic/rp_17.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 @@ -21,14 +21,22 @@ #include <dns/name.h> #include <dns/rdata.h> #include <dns/rdataclass.h> +#include <dns/rdata/generic/detail/lexer_util.h> using namespace std; using namespace isc::dns; using namespace isc::util; +using isc::dns::rdata::generic::detail::createNameFromLexer; // BEGIN_ISC_NAMESPACE // BEGIN_RDATA_NAMESPACE +// helper function for string and lexer constructors +void RP::constructFromLexer(MasterLexer& lexer, const Name* origin) { + mailbox_ = createNameFromLexer(lexer, origin); + text_ = createNameFromLexer(lexer, origin); +} + /// \brief Constructor from string. /// /// \c rp_str must be formatted as follows: @@ -36,32 +44,53 @@ using namespace isc::util; /// \endcode /// where both fields must represent a valid domain name. /// -/// \exception InvalidRdataText The number of RDATA fields (must be 2) is +/// \throw InvalidRdataText The number of RDATA fields (must be 2) is /// incorrect. -/// \exception Other The constructor of the \c Name class will throw if the +/// \throw Other The constructor of the \c Name class will throw if the /// given name is invalid. -/// \exception std::bad_alloc Memory allocation for names fails. +/// \throw std::bad_alloc Memory allocation for names fails. RP::RP(const std::string& rp_str) : // We cannot construct both names in the initialization list due to the // necessary text processing, so we have to initialize them with a dummy // name and replace them later. mailbox_(Name::ROOT_NAME()), text_(Name::ROOT_NAME()) { - istringstream iss(rp_str); - string mailbox_str, text_str; - iss >> mailbox_str >> text_str; - - // Validation: A valid RP RR must have exactly two fields. - if (iss.bad() || iss.fail()) { - isc_throw(InvalidRdataText, "Invalid RP text: " << rp_str); - } - if (!iss.eof()) { - isc_throw(InvalidRdataText, "Invalid RP text (redundant field): " - << rp_str); + try { + std::istringstream ss(rp_str); + MasterLexer lexer; + lexer.pushSource(ss); + + constructFromLexer(lexer, NULL); + + if (lexer.getNextToken().getType() != MasterToken::END_OF_FILE) { + isc_throw(InvalidRdataText, "extra input text for RP: " + << rp_str); + } + } catch (const MasterLexer::LexerError& ex) { + isc_throw(InvalidRdataText, "Failed to construct RP from '" << + rp_str << "': " << ex.what()); } +} - mailbox_ = Name(mailbox_str); - text_ = Name(text_str); +/// \brief Constructor with a context of MasterLexer. +/// +/// The \c lexer should point to the beginning of valid textual representation +/// of an RP RDATA. The MAILBOX and TEXT fields can be non-absolute if \c +/// origin is non-NULL, in which case \c origin is used to make them absolute. +/// +/// \throw MasterLexer::LexerError General parsing error such as missing field. +/// \throw Other Exceptions from the Name and constructors 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 SERVER when it +/// is non-absolute. +RP::RP(MasterLexer& lexer, const Name* origin, + MasterLoader::Options, MasterLoaderCallbacks&) : + mailbox_(Name::ROOT_NAME()), text_(Name::ROOT_NAME()) +{ + constructFromLexer(lexer, origin); } /// \brief Constructor from wire-format data. @@ -70,15 +99,15 @@ RP::RP(const std::string& rp_str) : /// length) for parsing. /// If necessary, the caller will check consistency. /// -/// \exception std::bad_alloc Memory allocation for names fails. -/// \exception Other The constructor of the \c Name class will throw if the +/// \throw std::bad_alloc Memory allocation for names fails. +/// \throw Other The constructor of the \c Name class will throw if the /// names in the wire is invalid. RP::RP(InputBuffer& buffer, size_t) : mailbox_(buffer), text_(buffer) { } /// \brief Copy constructor. /// -/// \exception std::bad_alloc Memory allocation fails in copying internal +/// \throw std::bad_alloc Memory allocation fails in copying internal /// member variables (this should be very rare). RP::RP(const RP& other) : Rdata(), mailbox_(other.mailbox_), text_(other.text_) @@ -89,7 +118,7 @@ RP::RP(const RP& other) : /// The output of this method is formatted as described in the "from string" /// constructor (\c RP(const std::string&))). /// -/// \exception std::bad_alloc Internal resource allocation fails. +/// \throw std::bad_alloc Internal resource allocation fails. /// /// \return A \c string object that represents the \c RP object. std::string diff --git a/src/lib/dns/rdata/generic/rp_17.h b/src/lib/dns/rdata/generic/rp_17.h index a90a530673..26478d856b 100644 --- a/src/lib/dns/rdata/generic/rp_17.h +++ b/src/lib/dns/rdata/generic/rp_17.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 @@ -75,6 +75,9 @@ public: Name getText() const { return (text_); } private: + // helper function for string and lexer constructors + void constructFromLexer(MasterLexer& lexer, const Name* origin); + Name mailbox_; Name text_; }; diff --git a/src/lib/dns/tests/rdata_rp_unittest.cc b/src/lib/dns/tests/rdata_rp_unittest.cc index 5508d9cd2e..e35440ed5b 100644 --- a/src/lib/dns/tests/rdata_rp_unittest.cc +++ b/src/lib/dns/tests/rdata_rp_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 @@ -41,6 +41,23 @@ protected: obuffer(0) {} + void checkFromText_LexerError(const string& rdata_str) { + checkFromText + <generic::RP, InvalidRdataText, MasterLexer::LexerError>( + rdata_str, rdata_rp, true, true); + } + + void checkFromText_MissingOrigin(const string& rdata_str) { + checkFromText + <generic::RP, MissingNameOrigin, MissingNameOrigin>( + rdata_str, rdata_rp, true, true); + } + + void checkFromText_EmptyLabel(const string& rdata_str) { + checkFromText<generic::RP, EmptyLabel, EmptyLabel>( + rdata_str, rdata_rp, true, true); + } + const Name mailbox_name, text_name; const generic::RP rdata_rp; // commonly used test RDATA OutputBuffer obuffer; @@ -54,14 +71,15 @@ TEST_F(Rdata_RP_Test, createFromText) { // Invalid textual input cases follow: // names are invalid - EXPECT_THROW(generic::RP("bad..name. rp-text.example.com"), EmptyLabel); - EXPECT_THROW(generic::RP("mailbox.example.com. bad..name"), EmptyLabel); + checkFromText_EmptyLabel("bad..name. rp-text.example.com."); + checkFromText_EmptyLabel("root.example.com. bad..name."); + checkFromText_MissingOrigin("root.example.com rp-text.example.com"); // missing field - EXPECT_THROW(generic::RP("mailbox.example.com."), InvalidRdataText); + checkFromText_LexerError("root.example.com."); // redundant field - EXPECT_THROW(generic::RP("mailbox.example.com. rp-text.example.com. " + EXPECT_THROW(generic::RP("root.example.com. rp-text.example.com. " "redundant.example."), InvalidRdataText); } @@ -112,9 +130,21 @@ TEST_F(Rdata_RP_Test, createFromLexer) { "root.example.com. " "rp-text.example.com."))); + // test::createRdataUsingLexer() constructs relative to + // "example.org." origin. + EXPECT_EQ(0, generic::RP("root.example.org. rp-text.example.org.").compare( + *test::createRdataUsingLexer(RRType::RP(), RRClass::IN(), + "root rp-text"))); + // Exceptions cause NULL to be returned. EXPECT_FALSE(test::createRdataUsingLexer(RRType::RP(), RRClass::IN(), - "mailbox.example.com.")); + "root.example.com.")); + + // acceptable?? + EXPECT_NO_THROW(test::createRdataUsingLexer(RRType::RP(), RRClass::IN(), + "root.example.com. " + "rp-text.example.com. " + "redundant.example.com.")); } TEST_F(Rdata_RP_Test, toWireBuffer) { |