BIND 10 master, updated. 2972b769eaa87705120211afd0cd4c4a5984c1c4 [master] Merge branch 'trac2374'
BIND 10 source code commits
bind10-changes at lists.isc.org
Tue Nov 27 13:29:39 UTC 2012
The branch, master has been updated
via 2972b769eaa87705120211afd0cd4c4a5984c1c4 (commit)
via 522f3f2bd6d1b6a42e3052a1cfe7a1b0212ca118 (commit)
via c6ceedc0a1137cf4f9db6d11d63f8e825d99b68e (commit)
via 9904f524d6a3d1f83bfa0cf94751b323f64bc233 (commit)
via b7a45ac8c122152452dcfce2a57df332748075ca (commit)
via d337cce4951bc4585f4109823b64b64346d0d232 (commit)
via 70a7eb4ae1843148a27c6ed054f15293f8b9e848 (commit)
from f8f96f9e0a1b3627f813cabe1b8034d844395949 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 2972b769eaa87705120211afd0cd4c4a5984c1c4
Merge: f8f96f9 522f3f2
Author: Jelte Jansen <jelte at isc.org>
Date: Tue Nov 27 14:29:05 2012 +0100
[master] Merge branch 'trac2374'
commit 522f3f2bd6d1b6a42e3052a1cfe7a1b0212ca118
Author: Jelte Jansen <jelte at isc.org>
Date: Tue Nov 27 14:28:41 2012 +0100
[2374] Add one more test to numbers-that-are-strings
-----------------------------------------------------------------------
Summary of changes:
src/lib/dns/master_lexer.cc | 58 +++++++++-
src/lib/dns/master_lexer_state.h | 3 +-
src/lib/dns/tests/master_lexer_state_unittest.cc | 135 ++++++++++++++++++++++
3 files changed, 192 insertions(+), 4 deletions(-)
-----------------------------------------------------------------------
diff --git a/src/lib/dns/master_lexer.cc b/src/lib/dns/master_lexer.cc
index e569d03..164fe5f 100644
--- a/src/lib/dns/master_lexer.cc
+++ b/src/lib/dns/master_lexer.cc
@@ -30,7 +30,7 @@ namespace dns {
namespace {
typedef boost::shared_ptr<master_lexer_internal::InputSource> InputSourcePtr;
-}
+} // end unnamed namespace
using namespace master_lexer_internal;
@@ -213,7 +213,7 @@ const char* const error_text[] = {
"no token produced" // NO_TOKEN_PRODUCED
};
const size_t error_text_max_count = sizeof(error_text) / sizeof(error_text[0]);
-}
+} // end unnamed namespace
std::string
MasterLexer::Token::getErrorText() const {
@@ -288,6 +288,13 @@ public:
virtual void handle(MasterLexer& lexer) const;
};
+class Number : public State {
+public:
+ Number() {}
+ virtual ~Number() {}
+ virtual const State* handle(MasterLexer& lexer) const;
+};
+
// We use a common instance of a each state in a singleton-like way to save
// construction overhead. They are not singletons in its strict sense as
// we don't prohibit direct construction of these objects. But that doesn't
@@ -296,7 +303,8 @@ public:
const CRLF CRLF_STATE;
const String STRING_STATE;
const QString QSTRING_STATE;
-}
+const Number NUMBER_STATE;
+} // end unnamed namespace
const State&
State::getInstance(ID state_id) {
@@ -307,6 +315,8 @@ State::getInstance(ID state_id) {
return (STRING_STATE);
case QString:
return (QSTRING_STATE);
+ case Number:
+ return (NUMBER_STATE);
}
// This is a bug of the caller, and this method is only expected to be
@@ -367,6 +377,11 @@ State::start(MasterLexer& lexer, MasterLexer::Options options) {
return (NULL);
}
--paren_count;
+ } else if (isdigit(c)) {
+ lexerimpl.last_was_eol_ = false;
+ // this character will be handled in the number state
+ lexerimpl.source_->ungetChar();
+ return (&NUMBER_STATE);
} else {
// this character will be handled in the string state
lexerimpl.source_->ungetChar();
@@ -431,6 +446,43 @@ QString::handle(MasterLexer& lexer) const {
}
}
+const State*
+Number::handle(MasterLexer& lexer) const {
+ MasterLexer::Token& token = getLexerImpl(lexer)->token_;
+ // Do we want to support octal and/or hex here?
+ const int base = 10;
+
+ // It may yet turn out to be a string, so we first
+ // collect all the data
+ bool digits_only = true;
+ std::vector<char>& data = getLexerImpl(lexer)->data_;
+ data.clear();
+ bool escaped = false;
+
+ while (true) {
+ const int c = getLexerImpl(lexer)->skipComment(
+ getLexerImpl(lexer)->source_->getChar(), escaped);
+ if (getLexerImpl(lexer)->isTokenEnd(c, escaped)) {
+ getLexerImpl(lexer)->source_->ungetChar();
+ if (digits_only) {
+ // Close the string for strtoul
+ data.push_back('\0');
+ token = MasterLexer::Token(strtoul(&data.at(0),
+ NULL, base));
+ } else {
+ token = MasterLexer::Token(&data.at(0),
+ data.size());
+ }
+ return (NULL);
+ }
+ if (!isdigit(c)) {
+ digits_only = false;
+ }
+ escaped = (c == '\\' && !escaped);
+ data.push_back(c);
+ }
+}
+
} // namespace master_lexer_internal
} // end of namespace dns
diff --git a/src/lib/dns/master_lexer_state.h b/src/lib/dns/master_lexer_state.h
index af9c1e9..2a64c9d 100644
--- a/src/lib/dns/master_lexer_state.h
+++ b/src/lib/dns/master_lexer_state.h
@@ -101,7 +101,8 @@ public:
enum ID {
CRLF, ///< Just seen a carriage-return character
String, ///< Handling a string token
- QString ///< Handling a quoted string token
+ QString, ///< Handling a quoted string token
+ Number ///< Handling a number
};
/// \brief Returns a \c State instance of the given state.
diff --git a/src/lib/dns/tests/master_lexer_state_unittest.cc b/src/lib/dns/tests/master_lexer_state_unittest.cc
index d2208fd..d2a4945 100644
--- a/src/lib/dns/tests/master_lexer_state_unittest.cc
+++ b/src/lib/dns/tests/master_lexer_state_unittest.cc
@@ -33,6 +33,7 @@ protected:
s_crlf(State::getInstance(State::CRLF)),
s_string(State::getInstance(State::String)),
s_qstring(State::getInstance(State::QString)),
+ s_number(State::getInstance(State::Number)),
options(MasterLexer::NONE),
orig_options(options)
{}
@@ -44,6 +45,7 @@ protected:
const State& s_crlf;
const State& s_string;
const State& s_qstring;
+ const State& s_number;
std::stringstream ss;
MasterLexer::Options options, orig_options;
};
@@ -450,4 +452,137 @@ TEST_F(MasterLexerStateTest, brokenQuotedString) {
EXPECT_EQ(Token::END_OF_FILE, s_crlf.getToken(lexer).getType());
}
+TEST_F(MasterLexerStateTest, basicNumbers) {
+ ss << "0 ";
+ ss << "1 ";
+ ss << "12345 ";
+ ss << "4294967295 "; // 2^32-1
+ ss << "4294967296 "; // 2^32 (this overflows to 0, we
+ // can consider failing on it, but
+ // this is what bind9 does as well)
+ ss << "4294967297 "; // 2^32+1 (this overflows to 1, see
+ // above)
+ ss << "1000000000000000000 "; // overflows to 2808348672
+ ss << "005 "; // Leading zeroes are ignored
+ ss << "42;asdf\n"; // Number with comment
+ ss << "37"; // Simple number again, here to make
+ // sure none of the above messed up
+ // the tokenizer
+ lexer.pushSource(ss);
+
+ EXPECT_EQ(&s_number, State::start(lexer, common_options));
+ EXPECT_EQ(s_null, s_number.handle(lexer));
+ EXPECT_EQ(0, s_number.getToken(lexer).getNumber());
+
+ EXPECT_EQ(&s_number, State::start(lexer, common_options));
+ EXPECT_EQ(s_null, s_number.handle(lexer));
+ EXPECT_EQ(1, s_number.getToken(lexer).getNumber());
+
+ EXPECT_EQ(&s_number, State::start(lexer, common_options));
+ EXPECT_EQ(s_null, s_number.handle(lexer));
+ EXPECT_EQ(12345, s_number.getToken(lexer).getNumber());
+
+ EXPECT_EQ(&s_number, State::start(lexer, common_options));
+ EXPECT_EQ(s_null, s_number.handle(lexer));
+ EXPECT_EQ(4294967295, s_number.getToken(lexer).getNumber());
+
+ EXPECT_EQ(&s_number, State::start(lexer, common_options));
+ EXPECT_EQ(s_null, s_number.handle(lexer));
+ EXPECT_EQ(0, s_number.getToken(lexer).getNumber());
+
+ EXPECT_EQ(&s_number, State::start(lexer, common_options));
+ EXPECT_EQ(s_null, s_number.handle(lexer));
+ EXPECT_EQ(1, s_number.getToken(lexer).getNumber());
+
+ EXPECT_EQ(&s_number, State::start(lexer, common_options));
+ EXPECT_EQ(s_null, s_number.handle(lexer));
+ EXPECT_EQ(2808348672, s_number.getToken(lexer).getNumber());
+
+ EXPECT_EQ(&s_number, State::start(lexer, common_options));
+ EXPECT_EQ(s_null, s_number.handle(lexer));
+ EXPECT_EQ(5, s_number.getToken(lexer).getNumber());
+
+ EXPECT_EQ(&s_number, State::start(lexer, common_options));
+ EXPECT_EQ(s_null, s_number.handle(lexer));
+ EXPECT_EQ(42, s_number.getToken(lexer).getNumber());
+
+ EXPECT_EQ(s_null, State::start(lexer, common_options));
+ EXPECT_TRUE(s_crlf.wasLastEOL(lexer));
+ EXPECT_EQ(Token::END_OF_LINE, s_crlf.getToken(lexer).getType());
+
+ EXPECT_EQ(&s_number, State::start(lexer, common_options));
+ EXPECT_EQ(s_null, s_number.handle(lexer));
+ EXPECT_EQ(37, s_number.getToken(lexer).getNumber());
+
+ // If we continue we'll simply see the EOF
+ EXPECT_EQ(s_null, State::start(lexer, options));
+ EXPECT_EQ(Token::END_OF_FILE, s_crlf.getToken(lexer).getType());
}
+
+// Test tokens that look like (or start out as) numbers,
+// but turn out to be strings. Tests include escaped characters.
+TEST_F(MasterLexerStateTest, stringNumbers) {
+ ss << "-1 "; // Negative numbers are interpreted
+ // as strings (unsigned integers only)
+ ss << "123abc456 "; // 'Numbers' containing non-digits should
+ // be interpreted as strings
+ ss << "123\\456 "; // Numbers containing escaped digits are
+ // interpreted as strings
+ ss << "3scaped\\ space ";
+ ss << "3scaped\\\ttab ";
+ ss << "3scaped\\(paren ";
+ ss << "3scaped\\)close ";
+ ss << "3scaped\\;comment ";
+ ss << "3scaped\\\\ 8ackslash "; // second '\' shouldn't escape ' '
+
+ lexer.pushSource(ss);
+
+ EXPECT_EQ(&s_string, State::start(lexer, common_options));
+ EXPECT_EQ(s_null, s_string.handle(lexer));
+ stringTokenCheck("-1", s_string.getToken(lexer), false);
+
+ // Starts out as a number, but ends up being a string
+ EXPECT_EQ(&s_number, State::start(lexer, common_options));
+ EXPECT_EQ(s_null, s_number.handle(lexer));
+ stringTokenCheck("123abc456", s_number.getToken(lexer), false);
+
+ EXPECT_EQ(&s_number, State::start(lexer, common_options));
+ EXPECT_EQ(s_null, s_number.handle(lexer));
+ stringTokenCheck("123\\456", s_number.getToken(lexer), false);
+
+ EXPECT_EQ(&s_number, State::start(lexer, common_options));
+ EXPECT_EQ(s_null, s_number.handle(lexer)); // recognize str, see ' ' at end
+ stringTokenCheck("3scaped\\ space", s_number.getToken(lexer));
+
+ EXPECT_EQ(&s_number, State::start(lexer, common_options));
+ EXPECT_EQ(s_null, s_number.handle(lexer)); // recognize str, see ' ' at end
+ stringTokenCheck("3scaped\\\ttab", s_number.getToken(lexer));
+
+ EXPECT_EQ(&s_number, State::start(lexer, common_options));
+ EXPECT_EQ(s_null, s_number.handle(lexer)); // recognize str, see ' ' at end
+ stringTokenCheck("3scaped\\(paren", s_number.getToken(lexer));
+
+ EXPECT_EQ(&s_number, State::start(lexer, common_options));
+ EXPECT_EQ(s_null, s_number.handle(lexer)); // recognize str, see ' ' at end
+ stringTokenCheck("3scaped\\)close", s_number.getToken(lexer));
+
+ EXPECT_EQ(&s_number, State::start(lexer, common_options));
+ EXPECT_EQ(s_null, s_number.handle(lexer)); // recognize str, see ' ' at end
+ stringTokenCheck("3scaped\\;comment", s_number.getToken(lexer));
+
+ EXPECT_EQ(&s_number, State::start(lexer, common_options));
+ EXPECT_EQ(s_null, s_number.handle(lexer)); // recognize str, see ' ' in mid
+ stringTokenCheck("3scaped\\\\", s_number.getToken(lexer));
+
+ // Confirm the word that follows the escaped '\' is correctly recognized.
+ EXPECT_EQ(&s_number, State::start(lexer, common_options));
+ EXPECT_EQ(s_null, s_number.handle(lexer)); // recognize str, see ' ' at end
+ stringTokenCheck("8ackslash", s_number.getToken(lexer));
+
+ // If we continue we'll simply see the EOF
+ EXPECT_EQ(s_null, State::start(lexer, options));
+ EXPECT_EQ(Token::END_OF_FILE, s_crlf.getToken(lexer).getType());
+}
+
+} // end anonymous namespace
+
More information about the bind10-changes
mailing list