Browse Source

[2373] supported escaping separaters

JINMEI Tatuya 12 years ago
parent
commit
b5d6b400ec
2 changed files with 44 additions and 4 deletions
  1. 8 4
      src/lib/dns/master_lexer.cc
  2. 36 0
      src/lib/dns/tests/master_lexer_state_unittest.cc

+ 8 - 4
src/lib/dns/master_lexer.cc

@@ -287,17 +287,21 @@ String::handle(MasterLexer& lexer) const {
     MasterLexer::Token& token = getLexerImpl(lexer)->token_;
     MasterLexer::Token& token = getLexerImpl(lexer)->token_;
     data.clear();
     data.clear();
 
 
+    bool escaped = false;
     while (true) {
     while (true) {
-        int c = getLexerImpl(lexer)->source_->getChar(); // TODO comment
-        c = getLexerImpl(lexer)->skipComment(c);
+        int c = getLexerImpl(lexer)->source_->getChar();
+        if (!escaped) {
+            c = getLexerImpl(lexer)->skipComment(c);
+        }
 
 
         if (c == '\r' || c == '\n' || c == EOF ||
         if (c == '\r' || c == '\n' || c == EOF ||
-            /* escape consideration */
-            c == ' ' || c == '\t' || c == '(' || c == ')') {
+            (!escaped &&
+             (c == ' ' || c == '\t' || c == '(' || c == ')'))) {
             getLexerImpl(lexer)->source_->ungetChar();
             getLexerImpl(lexer)->source_->ungetChar();
             token = MasterLexer::Token(&data.at(0), data.size());
             token = MasterLexer::Token(&data.at(0), data.size());
             return (NULL);
             return (NULL);
         }
         }
+        escaped = (!escaped && (c == '\\'));
         data.push_back(c);
         data.push_back(c);
     }
     }
 }
 }

+ 36 - 0
src/lib/dns/tests/master_lexer_state_unittest.cc

@@ -314,4 +314,40 @@ TEST_F(MasterLexerStateTest, string) {
     stringTokenCheck("followed-by-EOF", s_string.getToken(lexer));
     stringTokenCheck("followed-by-EOF", s_string.getToken(lexer));
 }
 }
 
 
+TEST_F(MasterLexerStateTest, stringEscape) {
+    // some of the separate characters should be considered part of the
+    // string if escaped.
+    ss << "escaped\\ space ";
+    ss << "escaped\\\ttab ";
+    ss << "escaped\\(paren ";
+    ss << "escaped\\)close ";
+    ss << "escaped\\;comment ";
+    ss << "escaped\\\\ backslash "; // second '\' shouldn't escape ' '
+    lexer.pushSource(ss);
+
+    EXPECT_EQ(&s_string, State::start(lexer, common_options));
+    EXPECT_EQ(s_null, s_string.handle(lexer)); // recognize str, see ' ' at end
+    stringTokenCheck("escaped\\ space", s_string.getToken(lexer));
+
+    EXPECT_EQ(&s_string, State::start(lexer, common_options));
+    EXPECT_EQ(s_null, s_string.handle(lexer)); // recognize str, see ' ' at end
+    stringTokenCheck("escaped\\\ttab", s_string.getToken(lexer));
+
+    EXPECT_EQ(&s_string, State::start(lexer, common_options));
+    EXPECT_EQ(s_null, s_string.handle(lexer)); // recognize str, see ' ' at end
+    stringTokenCheck("escaped\\(paren", s_string.getToken(lexer));
+
+    EXPECT_EQ(&s_string, State::start(lexer, common_options));
+    EXPECT_EQ(s_null, s_string.handle(lexer)); // recognize str, see ' ' at end
+    stringTokenCheck("escaped\\)close", s_string.getToken(lexer));
+
+    EXPECT_EQ(&s_string, State::start(lexer, common_options));
+    EXPECT_EQ(s_null, s_string.handle(lexer)); // recognize str, see ' ' at end
+    stringTokenCheck("escaped\\;comment", s_string.getToken(lexer));
+
+    EXPECT_EQ(&s_string, State::start(lexer, common_options));
+    EXPECT_EQ(s_null, s_string.handle(lexer)); // recognize str, see ' ' in mid
+    stringTokenCheck("escaped\\\\", s_string.getToken(lexer));
+}
+
 }
 }