Browse Source

[1332] detect read attempt and beyond the end of sequence and reject it by
exception. a new generic exception "InvalidOperation" was introduced.

JINMEI Tatuya 13 years ago
parent
commit
94ec743d73

+ 8 - 2
src/lib/datasrc/database.cc

@@ -1103,16 +1103,21 @@ public:
     DatabaseJournalReader(shared_ptr<Accessor> accessor, int zone_id,
                           const RRClass& rrclass, uint32_t begin,
                           uint32_t end) :
-        accessor_(accessor), rrclass_(rrclass)
+        accessor_(accessor), rrclass_(rrclass), finished_(false)
     {
         context_ = accessor_->getDiffs(zone_id, begin, end);
     }
     virtual ~DatabaseJournalReader() {}
     virtual ConstRRsetPtr getNextDiff() {
-        // TBD: check read after completion
+        if (finished_) {
+            isc_throw(InvalidOperation,
+                      "Diff read attempt past the end of sequence on "
+                      << accessor_->getDBName());
+        }
 
         string data[Accessor::COLUMN_COUNT];
         if (!context_->getNext(data)) {
+            finished_ = true;
             return (ConstRRsetPtr());
         }
 
@@ -1128,6 +1133,7 @@ private:
     shared_ptr<Accessor> accessor_;
     const RRClass rrclass_;
     Accessor::IteratorContextPtr context_;
+    bool finished_;
 };
 
 // The JournalReader factory

+ 6 - 0
src/lib/datasrc/tests/database_unittest.cc

@@ -19,6 +19,8 @@
 
 #include <gtest/gtest.h>
 
+#include <exceptions/exceptions.h>
+
 #include <dns/name.h>
 #include <dns/rrttl.h>
 #include <dns/rrset.h>
@@ -3108,6 +3110,10 @@ TYPED_TEST(DatabaseClientTest, journalReader) {
     isc::testutils::rrsetCheck(soa_end, rrset);
     rrset = jnl_reader->getNextDiff();
     ASSERT_FALSE(rrset);
+
+    // Once it reaches the end of the sequence, further read attempt will
+    // result in exception.
+    EXPECT_THROW(jnl_reader->getNextDiff(), isc::InvalidOperation);
 }
 
 TYPED_TEST(DatabaseClientTest, readLargeJournal) {

+ 11 - 0
src/lib/exceptions/exceptions.h

@@ -126,6 +126,17 @@ public:
         isc::Exception(file, line, what) {}
 };
 
+/// \brief A generic exception that is thrown if a function is called
+/// in a prohibited way.
+///
+/// For example, this can happen if a class method is called when the object's
+/// state does not allow that particular method.
+class InvalidOperation : public Exception {
+public:
+    InvalidOperation(const char* file, size_t line, const char* what) :
+        isc::Exception(file, line, what) {}
+};
+
 ///
 /// \brief A generic exception that is thrown when an unexpected
 /// error condition occurs.