Browse Source

[2267] catch and reject the bogus case of passing empty RRSIG

JINMEI Tatuya 12 years ago
parent
commit
f0d4fcf168

+ 9 - 1
src/lib/datasrc/memory/memory_client.cc

@@ -552,9 +552,17 @@ public:
         node_rrsigsets_.clear();
     }
 private:
+    // A helper to identify the covered type of an RRSIG.
     static RRType getCoveredType(const ConstRRsetPtr& sig_rrset) {
         RdataIteratorPtr it = sig_rrset->getRdataIterator();
-        // TBD: empty case
+        // Empty RRSIG shouldn't be passed either via a master file or another
+        // data source iterator, but it could still happen if the iterator
+        // has a bug.  We catch and reject such cases.
+        if (it->isLast()) {
+            isc_throw(isc::Unexpected,
+                      "Empty RRset is passed in-memory loader, name: "
+                      << sig_rrset->getName());
+        }
         return (dynamic_cast<const generic::RRSIG&>(it->getCurrent()).
                 typeCovered());
     }

+ 20 - 4
src/lib/datasrc/memory/tests/memory_client_unittest.cc

@@ -84,12 +84,16 @@ const char* rrset_data_sigseparated[] = {
 
 class MockIterator : public ZoneIterator {
 private:
-    MockIterator(const char** rrset_data_ptr) :
-        rrset_data_ptr_(rrset_data_ptr)
+    MockIterator(const char** rrset_data_ptr, bool pass_empty_rrsig) :
+        rrset_data_ptr_(rrset_data_ptr),
+        pass_empty_rrsig_(pass_empty_rrsig)
     {
     }
 
     const char** rrset_data_ptr_;
+    // If true, emulate an unexpected bogus case where an RRSIG RRset is
+    // returned without the RDATA.  For brevity allow tests tweak it directly.
+    bool pass_empty_rrsig_;
 
 public:
     virtual ConstRRsetPtr getNextRRset() {
@@ -99,6 +103,10 @@ public:
 
         ConstRRsetPtr result(textToRRset(*rrset_data_ptr_,
                                          RRClass::IN(), Name("example.org")));
+        if (pass_empty_rrsig_ && result->getType() == RRType::RRSIG()) {
+            result.reset(new RRset(result->getName(), result->getClass(),
+                                   result->getType(), result->getTTL()));
+        }
         ++rrset_data_ptr_;
 
         return (result);
@@ -108,8 +116,11 @@ public:
         isc_throw(isc::NotImplemented, "Not implemented");
     }
 
-    static ZoneIteratorPtr makeIterator(const char** rrset_data_ptr) {
-        return (ZoneIteratorPtr(new MockIterator(rrset_data_ptr)));
+    static ZoneIteratorPtr makeIterator(const char** rrset_data_ptr,
+                                        bool pass_empty_rrsig = false)
+    {
+        return (ZoneIteratorPtr(new MockIterator(rrset_data_ptr,
+                                                 pass_empty_rrsig)));
     }
 };
 
@@ -233,6 +244,11 @@ TEST_F(MemoryClientTest, loadFromIterator) {
                                *MockIterator::makeIterator(
                                    rrset_data_sigseparated)),
                  InMemoryClient::AddError);
+
+    // Emulating bogus iterator implementation that passes empty RRSIGs.
+    EXPECT_THROW(client_->load(Name("example.org"),
+                               *MockIterator::makeIterator(rrset_data, true)),
+                 isc::Unexpected);
 }
 
 TEST_F(MemoryClientTest, loadMemoryAllocationFailures) {