Parcourir la source

[2390] Update std::string MX constructor to use the MasterLexer

Also adjust tests.
Mukund Sivaraman il y a 12 ans
Parent
commit
e8c5250c5b

+ 2 - 2
src/lib/datasrc/tests/memory/rdata_serialization_unittest.cc

@@ -632,9 +632,9 @@ addRdataMultiCommon(const vector<ConstRdataPtr>& rrsigs) {
     checkEncode(RRClass::IN(), RRType::A(), rdata_list_, 0, rrsigs);
 
     ConstRdataPtr mx_rdata1 = createRdata(RRType::MX(), RRClass::IN(),
-                                          "5 mx1.example.com");
+                                          "5 mx1.example.com.");
     ConstRdataPtr mx_rdata2 = createRdata(RRType::MX(), RRClass::IN(),
-                                          "10 mx2.example.com");
+                                          "10 mx2.example.com.");
     rdata_list_.clear();
     rdata_list_.push_back(mx_rdata1);
     rdata_list_.push_back(mx_rdata2);

+ 24 - 13
src/lib/dns/rdata/generic/mx_15.cc

@@ -43,27 +43,38 @@ MX::MX(InputBuffer& buffer, size_t) :
 }
 
 MX::MX(const std::string& mx_str) :
-    preference_(0), mxname_(".")
+    // Fill in dummy name and replace them soon below.
+    preference_(0), mxname_(Name::ROOT_NAME())
 {
-    istringstream iss(mx_str);
-    uint16_t pref;
-    string mxname;
-
-    iss >> pref >> mxname;
-
-    if (iss.bad() || iss.fail() || !iss.eof()) {
-        isc_throw(InvalidRdataText, "Invalid MX text format");
+    try {
+        std::istringstream ss(mx_str);
+        MasterLexer lexer;
+        lexer.pushSource(ss);
+
+        const uint32_t num =
+            lexer.getNextToken(MasterToken::NUMBER).getNumber();
+        if (num > 65535) {
+            isc_throw(InvalidRdataText, "Invalid MX preference");
+        }
+        preference_ = static_cast<uint16_t>(num);
+
+        mxname_ = createNameFromLexer(lexer, NULL);
+
+        if (lexer.getNextToken().getType() != MasterToken::END_OF_FILE) {
+            isc_throw(InvalidRdataText, "extra input text for MX: "
+                      << mx_str);
+        }
+    } catch (const MasterLexer::LexerError& ex) {
+        isc_throw(InvalidRdataText, "Failed to construct MX from '" <<
+                  mx_str << "': " << ex.what());
     }
-
-    preference_ = pref;
-    mxname_ = Name(mxname);
 }
 
 MX::MX(MasterLexer& lexer, const Name* origin,
        MasterLoader::Options, MasterLoaderCallbacks&) :
     preference_(0), mxname_(".")
 {
-    uint32_t num = lexer.getNextToken(MasterToken::NUMBER).getNumber();
+    const uint32_t num = lexer.getNextToken(MasterToken::NUMBER).getNumber();
     if (num > 65535) {
         isc_throw(InvalidRdataText, "Invalid MX preference");
     }

+ 4 - 1
src/lib/dns/tests/rdata_mx_unittest.cc

@@ -38,7 +38,7 @@ class Rdata_MX_Test : public RdataTest {
 const generic::MX rdata_mx(10, Name("mx.example.com"));
 
 TEST_F(Rdata_MX_Test, createFromText) {
-    const generic::MX rdata_mx2("10 mx.example.com");
+    const generic::MX rdata_mx2("10 mx.example.com.");
     EXPECT_EQ(0, rdata_mx2.compare(rdata_mx));
 }
 
@@ -48,6 +48,9 @@ TEST_F(Rdata_MX_Test, badText) {
     EXPECT_THROW(const generic::MX rdata_mx("SPOON"), InvalidRdataText);
     EXPECT_THROW(const generic::MX rdata_mx("10 mx. example.com."),
                  InvalidRdataText);
+    // No origin and relative
+    EXPECT_THROW(const generic::MX rdata_mx("10 mx.example.com"),
+                 MissingNameOrigin);
 }
 
 TEST_F(Rdata_MX_Test, copy) {