initialized_(false),
ok_(true),
many_errors_((options & MANY_ERRORS) != 0),
- source_count_(0),
complete_(false),
- seen_error_(false)
+ seen_error_(false),
+ warn_rfc1035_ttl_(true)
{}
- void reportError(const std::string& filename, size_t line,
- const std::string& reason)
- {
- seen_error_ = true;
- callbacks_.error(filename, line, reason);
- if (!many_errors_) {
- // In case we don't have the lenient mode, every error is fatal
- // and we throw
- ok_ = false;
- complete_ = true;
- isc_throw(MasterLoaderError, reason.c_str());
- }
- }
-
void pushSource(const std::string& filename) {
std::string error;
if (!lexer_.pushSource(filename.c_str(), &error)) {
}
}
initialized_ = true;
- ++source_count_;
}
- ++source_count_;
+ void pushStreamSource(std::istream& stream) {
+ lexer_.pushSource(stream);
+ initialized_ = true;
+ }
+
+ bool loadIncremental(size_t count_limit);
+
+ private:
+ void reportError(const std::string& filename, size_t line,
+ const std::string& reason)
+ {
+ seen_error_ = true;
+ callbacks_.error(filename, line, reason);
+ if (!many_errors_) {
+ // In case we don't have the lenient mode, every error is fatal
+ // and we throw
+ ok_ = false;
+ complete_ = true;
+ isc_throw(MasterLoaderError, reason.c_str());
+ }
+ }
+
bool popSource() {
- if (--source_count_ == 0) {
+ if (lexer_.getSourceCount() == 1) {
return (false);
}
lexer_.popSource();
struct ErrorCase {
const char* const line; // The broken line in master file
+ const char* const reason; // If non NULL, the reason string
const char* const problem; // Description of the problem for SCOPED_TRACE
} const error_cases[] = {
- { "www... 3600 IN A 192.0.2.1", "Invalid name" },
- { "www FORTNIGHT IN A 192.0.2.1", "Invalid TTL" },
- { "www 3600 XX A 192.0.2.1", "Invalid class" },
- { "www 3600 IN A bad_ip", "Invalid Rdata" },
- { "www 3600 IN", "Unexpected EOLN" },
- { "www 3600 CH TXT nothing", "Class mismatch" },
- { "www \"3600\" IN A 192.0.2.1", "Quoted TTL" },
- { "www 3600 \"IN\" A 192.0.2.1", "Quoted class" },
- { "www 3600 IN \"A\" 192.0.2.1", "Quoted type" },
- { "unbalanced)paren 3600 IN A 192.0.2.1", "Token error 1" },
- { "www 3600 unbalanced)paren A 192.0.2.1", "Token error 2" },
+ { "www... 3600 IN A 192.0.2.1", NULL, "Invalid name" },
+ { "www FORTNIGHT IN A 192.0.2.1", NULL, "Invalid TTL" },
+ { "www 3600 XX A 192.0.2.1", NULL, "Invalid class" },
+ { "www 3600 IN A bad_ip", NULL, "Invalid Rdata" },
+ { "www 3600 IN", NULL, "Unexpected EOLN" },
+ { "www 3600 CH TXT nothing", NULL, "Class mismatch" },
+ { "www \"3600\" IN A 192.0.2.1", NULL, "Quoted TTL" },
+ { "www 3600 \"IN\" A 192.0.2.1", NULL, "Quoted class" },
+ { "www 3600 IN \"A\" 192.0.2.1", NULL, "Quoted type" },
+ { "unbalanced)paren 3600 IN A 192.0.2.1", NULL, "Token error 1" },
+ { "www 3600 unbalanced)paren A 192.0.2.1", NULL,
+ "Token error 2" },
// Check the unknown directive. The rest looks like ordinary RR,
// so we see the $ is actually special.
- { "$UNKNOWN 3600 IN A 192.0.2.1", "Unknown $ directive" },
- { "$INCLUD " TEST_DATA_SRCDIR "/example.org", "Include too short" },
- { "$INCLUDES " TEST_DATA_SRCDIR "/example.org", "Include too long" },
- { "$INCLUDE", "Missing include path" },
- { "$INCLUDE /file/not/found", "Include file not found" },
- { "$INCLUDE /file/not/found and here goes bunch of garbage",
+ { "$UNKNOWN 3600 IN A 192.0.2.1", NULL, "Unknown $ directive" },
++ { "$INCLUD " TEST_DATA_SRCDIR "/example.org", NULL, "Include too short" },
++ { "$INCLUDES " TEST_DATA_SRCDIR "/example.org", NULL, "Include too long" },
+ { "$INCLUDE", NULL, "Missing include path" },
+ { "$INCLUDE /file/not/found", NULL, "Include file not found" },
+ { "$INCLUDE /file/not/found and here goes bunch of garbage", NULL,
"Include file not found and garbage at the end of line" },
- { NULL, NULL }
+ { "$TTL 100 extra-garbage", "Extra tokens at the end of line",
+ "$TTL with extra token" },
+ { "$TTL", "unexpected end of input", "missing TTL" },
+ { "$TTL No-ttl", "Unknown unit used: N in: No-ttl", "bad TTL" },
+ { "$TTL \"100\"", "invalid TTL: \"100\"", "bad TTL, quoted" },
+ { "$TT 100", "Unknown directive 'TT'", "bad directive, too short" },
+ { "$TTLLIKE 100", "Unknown directive 'TTLLIKE'", "bad directive, extra" },
+ { NULL, NULL, NULL }
};
+ // A commonly used helper to check callback message.
+ void
+ checkCallbackMessage(const string& actual_msg, const string& expected_msg,
+ size_t expected_line) {
+ // The actual message should begin with the expected message.
+ EXPECT_EQ(0, actual_msg.find(expected_msg)) << "actual message: "
+ << actual_msg;
+
+ // and it should end with "...:<line_num>]"
+ const string line_desc = ":" + lexical_cast<string>(expected_line) + "]";
+ EXPECT_EQ(actual_msg.size() - line_desc.size(), actual_msg.find(line_desc));
+ }
+
// Test a broken zone is handled properly. We test several problems,
// both in strict and lenient mode.
TEST_F(MasterLoaderTest, brokenZone) {