Browse Source

[2372] handle non-closed parenthesis error.

JINMEI Tatuya 12 years ago
parent
commit
9fcdf4d524
2 changed files with 21 additions and 6 deletions
  1. 11 5
      src/lib/dns/master_lexer.cc
  2. 10 1
      src/lib/dns/tests/master_lexer_state_unittest.cc

+ 11 - 5
src/lib/dns/master_lexer.cc

@@ -202,10 +202,16 @@ cancelOptions(MasterLexer::Options& options,
 
 const State*
 Start::handle(MasterLexer& lexer, MasterLexer::Options& options) const {
+    size_t& paren_count = getLexerImpl(lexer)->paren_count_;
+
     while (true) {
         const int c = getLexerImpl(lexer)->source_->getChar();
         if (c == InputSource::END_OF_STREAM) {
-            // TODO: handle unbalance cases
+            if (paren_count != 0) {
+                getLexerImpl(lexer)->token_ = Token(Token::UNBALANCED_PAREN);
+                paren_count = 0; // reset to 0; this helps in lenient mode.
+                return (NULL);
+            }
             getLexerImpl(lexer)->last_was_eol_ = false;
             getLexerImpl(lexer)->token_ = Token(Token::END_OF_FILE);
             return (NULL);
@@ -227,16 +233,16 @@ Start::handle(MasterLexer& lexer, MasterLexer::Options& options) const {
             getLexerImpl(lexer)->last_was_eol_ = false;
             cancelOptions(options,
                           MasterLexer::END_OF_LINE | MasterLexer::INITIAL_WS);
-            ++getLexerImpl(lexer)->paren_count_;
+            ++paren_count;
             continue;
         } else if (c == ')') {
             getLexerImpl(lexer)->last_was_eol_ = false;
-            if (getLexerImpl(lexer)->paren_count_ == 0) {
+            if (paren_count == 0) {
                 getLexerImpl(lexer)->token_ = Token(Token::UNBALANCED_PAREN);
                 return (NULL);
             }
-            --getLexerImpl(lexer)->paren_count_;
-            if (getLexerImpl(lexer)->paren_count_ == 0) {
+            --paren_count;
+            if (paren_count == 0) {
                 options = getLexerImpl(lexer)->orig_options_;
             }
             continue;

+ 10 - 1
src/lib/dns/tests/master_lexer_state_unittest.cc

@@ -117,7 +117,7 @@ TEST_F(MasterLexerStateTest, parentheses) {
 
     EXPECT_EQ(s_null, s_start.handle(lexer, options)); // handle \n
 
-    // Now handle '('.  It skips \n and recognize 'a' as strin
+    // Now handle '('.  It skips \n and recognize 'a' as string
     EXPECT_EQ(0, s_start.getParenCount(lexer)); // check pre condition
     options = MasterLexer::END_OF_LINE | MasterLexer::INITIAL_WS;
     // should recognize 'a' as string
@@ -177,6 +177,15 @@ TEST_F(MasterLexerStateTest, unbalancedParentheses) {
     ASSERT_EQ(Token::ERROR, s_start.getToken(lexer).getType());
     EXPECT_EQ(Token::UNBALANCED_PAREN, s_start.getToken(lexer).getErrorCode());
     EXPECT_FALSE(s_start.wasLastEOL(lexer));
+
+    // Reach EOF without a dangling open parenthesis.
+    ss << "(a";
+    EXPECT_EQ(&s_string, s_start.handle(lexer, options)); // consume '(a'
+    EXPECT_EQ(1, s_start.getParenCount(lexer));
+    EXPECT_EQ(s_null, s_start.handle(lexer, options));    // reach EOF
+    ASSERT_EQ(Token::ERROR, s_start.getToken(lexer).getType());
+    EXPECT_EQ(Token::UNBALANCED_PAREN, s_start.getToken(lexer).getErrorCode());
+    EXPECT_EQ(0, s_start.getParenCount(lexer));
 }
 
 }