Browse Source

[2108] Loading an empty zone without even an SOA for the origin should throw

Mukund Sivaraman 12 years ago
parent
commit
11fbb68418

+ 10 - 2
src/lib/datasrc/memory/memory_client.cc

@@ -561,19 +561,27 @@ InMemoryClient::InMemoryClientImpl::load(
 
     assert(!last_rrset_);
 
+    const ZoneNode* origin_node = holder.get()->getOriginNode();
+    const RdataSet* set = origin_node->getData();
     // If the zone is NSEC3-signed, check if it has NSEC3PARAM
     if (holder.get()->isNSEC3Signed()) {
         // Note: origin_data_ is set on creation of ZoneData, and the load
         // process only adds new nodes (and their data), so this assertion
         // should hold.
-        const ZoneNode* origin_node = holder.get()->getOriginNode();
-        const RdataSet* set = origin_node->getData();
         if (RdataSet::find(set, RRType::NSEC3PARAM()) == NULL) {
             LOG_WARN(logger, DATASRC_MEM_NO_NSEC3PARAM).
                 arg(zone_name).arg(rrclass_);
         }
     }
 
+    // When an empty zone file is loaded, the origin doesn't even have
+    // an SOA RR. This condition should be avoided, and hence load()
+    // should throw when an empty zone is loaded.
+    if (RdataSet::find(set, RRType::SOA()) == NULL) {
+        isc_throw(EmptyZone,
+                  "Won't create an empty zone for: " << zone_name);
+    }
+
     LOG_DEBUG(logger, DBG_TRACE_BASIC, DATASRC_MEM_ADD_ZONE).
         arg(zone_name).arg(rrclass_.toText());
 

+ 10 - 0
src/lib/datasrc/memory/memory_client.h

@@ -177,6 +177,16 @@ public:
         { }
     };
 
+    /// \brief Zone is empty exception.
+    ///
+    /// This is thrown if we have an empty zone created as a result of
+    /// load().
+    struct EmptyZone : public InvalidParameter {
+        EmptyZone(const char* file, size_t line, const char* what) :
+            InvalidParameter(file, line, what)
+        { }
+    };
+
     /// \brief General failure exception for \c add().
     ///
     /// This is thrown against general error cases in adding an RRset

+ 10 - 0
src/lib/datasrc/memory/tests/memory_client_unittest.cc

@@ -119,6 +119,16 @@ TEST_F(MemoryClientTest, loadNonExistentZoneFile) {
     // Teardown checks for memory segment leaks
 }
 
+TEST_F(MemoryClientTest, loadEmptyZoneFileThrows) {
+    // When an empty zone file is loaded, the origin doesn't even have
+    // an SOA RR. This condition should be avoided, and hence load()
+    // should throw when an empty zone is loaded.
+    EXPECT_THROW(client_->load(Name("."),
+                               TEST_DATA_DIR "/empty.zone"),
+                 InMemoryClient::EmptyZone);
+    // Teardown checks for memory segment leaks
+}
+
 TEST_F(MemoryClientTest, load) {
     // This is a simple load check for a "full" and correct zone that
     // should not result in any exceptions.

+ 2 - 1
src/lib/datasrc/memory/tests/testdata/Makefile.am

@@ -1,6 +1,7 @@
 CLEANFILES = *.copied
 
-EXTRA_DIST =  example.org.zone
+EXTRA_DIST =  empty.zone
+EXTRA_DIST += example.org.zone
 EXTRA_DIST += example.org-empty.zone
 EXTRA_DIST += example.org-broken1.zone
 EXTRA_DIST += example.org-broken2.zone

+ 0 - 0
src/lib/datasrc/memory/tests/testdata/empty.zone