Browse Source

[2506] handled the case when getNextToken expects a number but it's too big.

JINMEI Tatuya 12 years ago
parent
commit
597ed99f86
2 changed files with 30 additions and 16 deletions
  1. 6 0
      src/lib/dns/master_lexer.cc
  2. 24 16
      src/lib/dns/tests/master_lexer_unittest.cc

+ 6 - 0
src/lib/dns/master_lexer.cc

@@ -213,6 +213,12 @@ MasterLexer::getNextToken(MasterToken::Type expect, bool eol_ok) {
     // the result should be set in impl_->token_
     getNextToken(optionsForTokenType(expect));
 
+    if (impl_->token_.getType() == MasterToken::ERROR) {
+        //if (impl_->token_.getErrorCode() == MasterToken::NUMBER_OUT_OF_RANGE)
+        ungetToken();
+        throw LexerError(__FILE__, __LINE__, impl_->token_);
+    }
+
     const bool is_eol_like =
         (impl_->token_.getType() == MasterToken::END_OF_LINE ||
          impl_->token_.getType() == MasterToken::END_OF_FILE);

+ 24 - 16
src/lib/dns/tests/master_lexer_unittest.cc

@@ -284,6 +284,21 @@ TEST_F(MasterLexerTest, ungetAfterSwitch) {
     EXPECT_THROW(lexer.ungetToken(), isc::InvalidOperation);
 }
 
+// Common checks for the case when getNextToken() should result in LexerError
+void
+lexerErrorCheck(MasterLexer& lexer, MasterToken::Type expect,
+                MasterToken::ErrorCode expected_error)
+{
+    bool thrown = false;
+    try {
+        lexer.getNextToken(expect);
+    } catch (const MasterLexer::LexerError& error) {
+        EXPECT_EQ(expected_error, error.token_.getErrorCode());
+        thrown = true;
+    }
+    EXPECT_TRUE(thrown);
+}
+
 // Common checks regarding expected/unexpected end-of-line
 void
 eolCheck(MasterLexer& lexer, MasterToken::Type expect) {
@@ -297,14 +312,7 @@ eolCheck(MasterLexer& lexer, MasterToken::Type expect) {
     EXPECT_THROW(lexer.getNextToken(expect, false), MasterLexer::LexerError);
 
     // And also check the error token set in the exception object.
-    bool thrown = false;
-    try {
-        lexer.getNextToken(expect);
-    } catch (const MasterLexer::LexerError& error) {
-        EXPECT_EQ(MasterToken::UNEXPECTED_END, error.token_.getErrorCode());
-        thrown = true;
-    }
-    EXPECT_TRUE(thrown);
+    lexerErrorCheck(lexer, expect, MasterToken::UNEXPECTED_END);
 }
 
 // Common checks regarding expected/unexpected end-of-file
@@ -359,6 +367,7 @@ TEST_F(MasterLexerTest, getNextTokenQString) {
 TEST_F(MasterLexerTest, getNextTokenNumber) {
     ss << "3600\n";
     ss << "\n";
+    ss << "4294967296 ";        // =2^32, out of range
     ss << "not-a-number ";
     ss << "86400";
     lexer.pushSource(ss);
@@ -371,15 +380,14 @@ TEST_F(MasterLexerTest, getNextTokenNumber) {
     // Skip the 2nd '\n'
     EXPECT_EQ(MasterToken::END_OF_LINE, lexer.getNextToken().getType());
 
+    // Expecting a number, but it's too big for uint32.
+    lexerErrorCheck(lexer, MasterToken::NUMBER,
+                    MasterToken::NUMBER_OUT_OF_RANGE);
+    // The token should have been "ungotten".  Re-read and skip it.
+    EXPECT_EQ(MasterToken::STRING, lexer.getNextToken().getType());
+
     // Expecting a number, but see a string.
-    bool thrown = false;
-    try {
-        lexer.getNextToken(MasterToken::NUMBER);
-    } catch (const MasterLexer::LexerError& error) {
-        EXPECT_EQ(MasterToken::BAD_NUMBER, error.token_.getErrorCode());
-        thrown = true;
-    }
-    EXPECT_TRUE(thrown);
+    lexerErrorCheck(lexer, MasterToken::NUMBER, MasterToken::BAD_NUMBER);
     // The unexpected string should have been "ungotten".  Re-read and skip it.
     EXPECT_EQ(MasterToken::STRING, lexer.getNextToken().getType());