Browse Source

[2377] Defence of MasterLoader

Reject invalid parameters and invalid attempts to load twice.
Michal 'vorner' Vaner 12 years ago
parent
commit
fd7f3a84f3
2 changed files with 30 additions and 2 deletions
  1. 14 2
      src/lib/dns/master_loader.cc
  2. 16 0
      src/lib/dns/tests/master_loader_unittest.cc

+ 14 - 2
src/lib/dns/master_loader.cc

@@ -41,7 +41,8 @@ public:
         options_(options),
         master_file_(master_file),
         initialized_(false),
-        ok_(true)
+        ok_(true),
+        complete_(false)
     {}
 
     void pushSource(const std::string& filename) {
@@ -58,6 +59,10 @@ public:
     }
 
     bool loadIncremental(size_t count_limit) {
+        if (complete_) {
+            isc_throw(isc::InvalidOperation,
+                      "Trying to load when already loaded");
+        }
         if (!initialized_) {
             pushSource(master_file_);
             initialized_ = true;
@@ -161,6 +166,8 @@ private:
     const std::string master_file_;
     bool initialized_;
     bool ok_;
+public:
+    bool complete_;
 };
 
 MasterLoader::MasterLoader(const char* master_file,
@@ -170,6 +177,9 @@ MasterLoader::MasterLoader(const char* master_file,
                            const AddRRCallback& add_callback,
                            Options options)
 {
+    if (add_callback.empty()) {
+        isc_throw(isc::InvalidParameter, "Empty add RR callback");
+    }
     impl_ = new MasterLoaderImpl(master_file, zone_origin,
                                  zone_class, callbacks, add_callback, options);
 }
@@ -180,7 +190,9 @@ MasterLoader::~MasterLoader() {
 
 bool
 MasterLoader::loadIncremental(size_t count_limit) {
-    return (impl_->loadIncremental(count_limit));
+    bool result = impl_->loadIncremental(count_limit);
+    impl_->complete_ = result;
+    return (result);
 }
 
 } // end namespace dns

+ 16 - 0
src/lib/dns/tests/master_loader_unittest.cc

@@ -227,3 +227,19 @@ TEST_F(MasterLoaderTest, brokenZone) {
         }
     }
 }
+
+// Test the constructor rejects empty add callback.
+TEST_F(MasterLoaderTest, emptyCallback) {
+    EXPECT_THROW(MasterLoader(TEST_DATA_SRCDIR "/example.org",
+                              Name("example.org"), RRClass::IN(), callbacks_,
+                              AddRRCallback()), isc::InvalidParameter);
+}
+
+// Check it throws when we try to load after loading was complete.
+TEST_F(MasterLoaderTest, loadTwice) {
+    setLoader(TEST_DATA_SRCDIR "/example.org", Name("example.org."),
+              RRClass::IN(), MasterLoader::MANY_ERRORS);
+
+    loader_->load();
+    EXPECT_THROW(loader_->load(), isc::InvalidOperation);
+}