Browse Source

[2000] Add more fromWire() tests

Mukund Sivaraman 11 years ago
parent
commit
e2c4caa239

+ 7 - 3
src/lib/dns/rdata/generic/opt_41.cc

@@ -111,7 +111,9 @@ OPT::OPT(InputBuffer& buffer, size_t rdata_len) :
         const uint16_t option_length = buffer.readUint16();
         rdata_len -= 4;
 
-        if ((impl_ptr->rdlength_ + option_length) < impl_ptr->rdlength_) {
+        if (static_cast<uint16_t>(impl_ptr->rdlength_ + option_length) <
+            impl_ptr->rdlength_)
+        {
             isc_throw(InvalidRdataText,
                       "Option length " << option_length
                       << " would overflow OPT RR RDLEN (currently "
@@ -119,7 +121,7 @@ OPT::OPT(InputBuffer& buffer, size_t rdata_len) :
         }
 
         if (rdata_len < option_length) {
-            isc_throw(InvalidRdataLength, "Corrupt Pseudo OPT RR record");
+            isc_throw(InvalidRdataLength, "Corrupt pseudo OPT RR record");
         }
 
         boost::shared_ptr<std::vector<uint8_t> >
@@ -184,7 +186,9 @@ OPT::appendPseudoRR(uint16_t code, const uint8_t* data, uint16_t length) {
     // See if it overflows 16-bit length field. We only worry about the
     // pseudo-RR length here, not the whole message length (which should
     // be checked and enforced elsewhere).
-    if ((impl_->rdlength_ + length) < impl_->rdlength_) {
+    if (static_cast<uint16_t>(impl_->rdlength_ + length) <
+        impl_->rdlength_)
+    {
         isc_throw(isc::InvalidParameter,
                   "Option length " << length
                   << " would overflow OPT RR RDLEN (currently "

+ 20 - 5
src/lib/dns/tests/rdata_opt_unittest.cc

@@ -46,12 +46,27 @@ TEST_F(Rdata_OPT_Test, createFromWire) {
     // Valid cases: in the simple implementation with no supported options,
     // we can only check these don't throw.
     EXPECT_NO_THROW(rdataFactoryFromFile(RRType::OPT(), RRClass("CLASS4096"),
-                                         "rdata_opt_fromWire"));
+                                         "rdata_opt_fromWire1"));
     EXPECT_NO_THROW(rdataFactoryFromFile(RRType::OPT(), RRClass::CH(),
-                                         "rdata_opt_fromWire", 2));
+                                         "rdata_opt_fromWire1", 2));
+
+    // Short RDLEN. This throws InvalidRdataLength even if subsequent
+    // pseudo RRs cause RDLEN size to be exhausted.
+    EXPECT_THROW(rdataFactoryFromFile(RRType::OPT(), RRClass::IN(),
+                                      "rdata_opt_fromWire2"),
+                 InvalidRdataLength);
+    EXPECT_THROW(rdataFactoryFromFile(RRType::OPT(), RRClass::IN(),
+                                      "rdata_opt_fromWire3"),
+                 InvalidRdataLength);
+    // Option lengths can add up and overflow RDLEN. Unlikely when
+    // parsed from wire data, but we'll check for it anyway.
+    EXPECT_THROW(rdataFactoryFromFile(RRType::OPT(), RRClass::IN(),
+                                      "rdata_opt_fromWire4"),
+                 InvalidRdataText);
+
     // short buffer case.
     EXPECT_THROW(rdataFactoryFromFile(RRType::OPT(), RRClass::IN(),
-                                      "rdata_opt_fromWire", 11),
+                                      "rdata_opt_fromWire1", 11),
                  InvalidBufferPosition);
 }
 
@@ -80,7 +95,7 @@ TEST_F(Rdata_OPT_Test, toText) {
 TEST_F(Rdata_OPT_Test, compare) {
     EXPECT_THROW(rdata_opt.compare(
                   *rdataFactoryFromFile(RRType::OPT(), RRClass::CH(),
-                                        "rdata_opt_fromWire", 2)),
+                                        "rdata_opt_fromWire1", 2)),
                  isc::InvalidOperation);
 
     // comparison attempt between incompatible RR types also results in
@@ -98,7 +113,7 @@ TEST_F(Rdata_OPT_Test, getPseudoRRs) {
     const generic::OPT rdf =
         dynamic_cast<const generic::OPT&>
         (*rdataFactoryFromFile(RRType("OPT"), RRClass("IN"),
-                               "rdata_opt_fromWire", 2));
+                               "rdata_opt_fromWire1", 2));
 
     const std::vector<generic::OPT::PseudoRR>& rrs = rdf.getPseudoRRs();
     ASSERT_FALSE(rrs.empty());

+ 3 - 1
src/lib/dns/tests/testdata/Makefile.am

@@ -127,7 +127,9 @@ EXTRA_DIST += rdata_nsec3_fromWire10.spec rdata_nsec3_fromWire11.spec
 EXTRA_DIST += rdata_nsec3_fromWire12.spec rdata_nsec3_fromWire13.spec
 EXTRA_DIST += rdata_nsec3_fromWire14.spec rdata_nsec3_fromWire15.spec
 EXTRA_DIST += rdata_nsec3_fromWire16.spec rdata_nsec3_fromWire17.spec
-EXTRA_DIST += rdata_opt_fromWire rdata_rrsig_fromWire1
+EXTRA_DIST += rdata_opt_fromWire1 rdata_opt_fromWire2
+EXTRA_DIST += rdata_opt_fromWire3 rdata_opt_fromWire4
+EXTRA_DIST += rdata_rrsig_fromWire1
 EXTRA_DIST += rdata_rrsig_fromWire2.spec
 EXTRA_DIST += rdata_rp_fromWire1.spec rdata_rp_fromWire2.spec
 EXTRA_DIST += rdata_rp_fromWire3.spec rdata_rp_fromWire4.spec

src/lib/dns/tests/testdata/rdata_opt_fromWire → src/lib/dns/tests/testdata/rdata_opt_fromWire1


+ 4 - 0
src/lib/dns/tests/testdata/rdata_opt_fromWire2

@@ -0,0 +1,4 @@
+# short RDATA length
+#
+# OPT RDATA, RDLEN=1
+0001

+ 8 - 0
src/lib/dns/tests/testdata/rdata_opt_fromWire3

@@ -0,0 +1,8 @@
+# short RDATA length (in second pseudo RR)
+#
+# OPT RDATA, RDLEN=8
+0008
+# psuedo RR 1 of size 7 (code=3, len=3)
+00 03 00 03 00 01 02
+# psuedo RR 2 of size 7 exhausts RDLEN (code=4, len=3)
+00 04 00 03 00 01 02

+ 9 - 0
src/lib/dns/tests/testdata/rdata_opt_fromWire4

@@ -0,0 +1,9 @@
+# Sum of option lengths would overflow RDLEN
+#
+# OPT RDATA, RDLEN=14 (0x000e)
+000e
+# psuedo RR 1 (code=3, len=3)
+00 03 00 03 00 01 02
+# psuedo RR 2 (code=4, len=65535 overflows RDLEN)
+00 04 ff ff 00 01 02
+# rest of option data is omitted...