Parcourir la source

[2428] Do pop even after error

Michal 'vorner' Vaner il y a 12 ans
Parent
commit
33fb59eeb6

+ 5 - 3
src/lib/dns/master_loader.cc

@@ -285,9 +285,11 @@ MasterLoader::MasterLoaderImpl::loadIncremental(size_t count_limit) {
                         callbacks_.warning(lexer_.getSourceName(),
                                            lexer_.getSourceLine(),
                                            "Unexpected end ond of file");
-                        // TODO: Try pop in case this is not the only
-                        // source
-                        return (true);
+                        if (!popSource()) {
+                            return (true);
+                        }
+                        // Else: fall through, the popped source is
+                        // at the end of line currently
                     case MasterToken::END_OF_LINE:
                         end = true;
                         break;

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

@@ -158,6 +158,8 @@ TEST_F(MasterLoaderTest, include) {
     };
     for (const char** include = includes; *include != NULL; ++include) {
         SCOPED_TRACE(*include);
+
+        clear();
         // Prepare input source that has the include and some more data
         // below (to see it returns back to the original source).
         const string include_str = "$" + string(*include) + " " +
@@ -176,6 +178,26 @@ TEST_F(MasterLoaderTest, include) {
     }
 }
 
+// Test the source is correctly popped even after error
+TEST_F(MasterLoaderTest, popAfterError) {
+    const string include_str = "$include " TEST_DATA_SRCDIR
+        "/broken.zone\nwww 3600 IN AAAA 2001:db8::1\n";
+    stringstream ss(include_str);
+    // We don't test without MANY_ERRORS, we want to see what happens
+    // after the error.
+    setLoader(ss, Name("example.org."), RRClass::IN(),
+              MasterLoader::MANY_ERRORS);
+
+    loader_->load();
+    EXPECT_FALSE(loader_->loadedSucessfully());
+    EXPECT_EQ(1, errors_.size()); // For the broken RR
+    EXPECT_EQ(1, warnings_.size()); // For missing EOLN
+
+    // The included file doesn't contain anything usable, but the
+    // line after the include should be there.
+    checkRR("www.example.org", RRType::AAAA(), "2001:db8::1");
+}
+
 // Check it works the same when created based on a stream, not filename
 TEST_F(MasterLoaderTest, streamConstructor) {
     stringstream zone_stream(prepareZone("", true));

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

@@ -171,6 +171,7 @@ EXTRA_DIST += tsig_verify4.spec tsig_verify5.spec tsig_verify6.spec
 EXTRA_DIST += tsig_verify7.spec tsig_verify8.spec tsig_verify9.spec
 EXTRA_DIST += tsig_verify10.spec
 EXTRA_DIST += example.org
+EXTRA_DIST += broken.zone
 
 .spec.wire:
 	$(PYTHON) $(top_builddir)/src/lib/util/python/gen_wiredata.py -o $@ $<

+ 3 - 0
src/lib/dns/tests/testdata/broken.zone

@@ -0,0 +1,3 @@
+; This should fail due to broken TTL
+; The file should _NOT_ end with EOLN
+broken.     3600X   IN  A   192.0.2.2 More data