BIND 10 trac1112, updated. 9f441d72a245e3ccce2ee014adaa0ad62e7b0d29 [trac1112] Add escaped characters support and unit tests to to characterstr class

BIND 10 source code commits bind10-changes at lists.isc.org
Wed Sep 14 09:09:47 UTC 2011


The branch, trac1112 has been updated
       via  9f441d72a245e3ccce2ee014adaa0ad62e7b0d29 (commit)
      from  88095bed9cbc3e39c61eb0ea7dee1646ff13ac7e (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 9f441d72a245e3ccce2ee014adaa0ad62e7b0d29
Author: Ocean Wang <wanghaidong at cnnic.cn>
Date:   Wed Sep 14 17:08:17 2011 +0800

    [trac1112] Add escaped characters support and unit tests to to characterstr class

-----------------------------------------------------------------------

Summary of changes:
 src/lib/dns/character_string.cc                |   63 +++++++++++++---
 src/lib/dns/tests/Makefile.am                  |    1 +
 src/lib/dns/tests/character_string_unittest.cc |   94 ++++++++++++++++++++++++
 3 files changed, 148 insertions(+), 10 deletions(-)
 create mode 100644 src/lib/dns/tests/character_string_unittest.cc

-----------------------------------------------------------------------
diff --git a/src/lib/dns/character_string.cc b/src/lib/dns/character_string.cc
index c65ddcc..ae2ad7a 100644
--- a/src/lib/dns/character_string.cc
+++ b/src/lib/dns/character_string.cc
@@ -21,6 +21,8 @@ using namespace isc::dns::rdata;
 namespace isc {
 namespace dns {
 
+#define IS_DIGIT(c) (('0' <= (c)) && ((c) <= '9'))
+
 std::string
 characterstr::getNextCharacterString(const std::string& input_str,
                               std::string::const_iterator& input_iterator)
@@ -36,27 +38,64 @@ characterstr::getNextCharacterString(const std::string& input_str,
 
     // Whether the <character-string> is separated with double quotes (")
     bool quotes_separated = (*input_iterator == '"');
+    // Whether the quotes are pared if the string is quotes separated
+    bool quotes_paired = false;
 
     if (quotes_separated) {
         ++input_iterator;
     }
 
     while(input_iterator < input_str.end()){
+        // Escaped characters processing
+        if (*input_iterator == '\\') {
+            if (input_iterator + 1 == input_str.end()) {
+                isc_throw(InvalidRdataText, "<character-string> ended \
+                          exceptionally.");
+            } else {
+                if (IS_DIGIT(*(input_iterator + 1))) {
+                    // \DDD where each D is a digit. It its the octet
+                    // corresponding to the decimal number described by DDD
+                    if (input_iterator + 3 >= input_str.end()) {
+                        isc_throw(InvalidRdataText, "<character-string> ended \
+                                  exceptionally.");
+                    } else {
+                        int n = 0;
+                        ++input_iterator;
+                        for (int i = 0; i < 3; ++i) {
+                            if (('0' <= *input_iterator) &&
+                                (*input_iterator <= '9')) {
+                                n = n*10 + (*input_iterator - '0');
+                                ++input_iterator;
+                            } else {
+                                isc_throw(InvalidRdataText, "Illegal decimal \
+                                          escaping series");
+                            }
+                        }
+                        if (n > 255) {
+                            isc_throw(InvalidRdataText, "Illegal octet \
+                                      number");
+                        }
+                        result.push_back(n);
+                        continue;
+                    }
+                } else {
+                    ++input_iterator;
+                    result.push_back(*input_iterator);
+                    ++input_iterator;
+                    continue;
+                }
+            }
+        }
+
         if (quotes_separated) {
             // If the <character-string> is seperated with quotes symbol and
             // another quotes symbol is encountered, it is the end of the
             // <character-string>
             if (*input_iterator == '"') {
-                // Inside a " delimited string any character can occur, except
-                // for a " itself, which must be quoted using \ (back slash).
-                if (*(input_iterator - 1) == '\\') {
-                    // pop the '\' character
-                    result.resize(result.size() - 1);
-                } else {
-                    ++input_iterator;
-                    // Reach the end of character string
-                    break;
-                }
+                quotes_paired = true;
+                ++input_iterator;
+                // Reach the end of character string
+                break;
             }
         } else if (*input_iterator == ' ') {
             // If the <character-string> is not seperated with quotes symbol,
@@ -73,6 +112,10 @@ characterstr::getNextCharacterString(const std::string& input_str,
         isc_throw(CharStringTooLong, "<character-string> is too long");
     }
 
+    if (quotes_separated && !quotes_paired) {
+        isc_throw(InvalidRdataText, "The quotes are not paired");
+    }
+
     return (result);
 }
 
diff --git a/src/lib/dns/tests/Makefile.am b/src/lib/dns/tests/Makefile.am
index d1a5025..5f90cea 100644
--- a/src/lib/dns/tests/Makefile.am
+++ b/src/lib/dns/tests/Makefile.am
@@ -56,6 +56,7 @@ run_unittests_SOURCES += tsig_unittest.cc
 run_unittests_SOURCES += tsigerror_unittest.cc
 run_unittests_SOURCES += tsigkey_unittest.cc
 run_unittests_SOURCES += tsigrecord_unittest.cc
+run_unittests_SOURCES += character_string_unittest.cc
 run_unittests_SOURCES += run_unittests.cc
 run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
 # We shouldn't need to include BOTAN_LDFLAGS here, but there
diff --git a/src/lib/dns/tests/character_string_unittest.cc b/src/lib/dns/tests/character_string_unittest.cc
new file mode 100644
index 0000000..83dbf92
--- /dev/null
+++ b/src/lib/dns/tests/character_string_unittest.cc
@@ -0,0 +1,94 @@
+// Copyright (C) 2011  Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+
+#include <gtest/gtest.h>
+
+#include <dns/rdata.h>
+#include <dns/tests/unittest_util.h>
+#include <dns/character_string.h>
+
+using isc::UnitTestUtil;
+
+using namespace std;
+using namespace isc;
+using namespace isc::dns;
+using namespace isc::dns::characterstr;
+using namespace isc::dns::rdata;
+
+namespace {
+class CharacterStringTest : public ::testing::Test {
+};
+
+class CharacterString {
+public:
+    CharacterString(const string& str){
+        string::const_iterator it = str.begin();
+        characterStr_ = getNextCharacterString(str, it);
+    }
+    const string& str() const { return characterStr_; }
+private:
+    string characterStr_;
+};
+
+TEST_F(CharacterStringTest, testNormalCase) {
+    CharacterString cstr1("foo");
+    EXPECT_EQ(string("foo"), cstr1.str());
+
+    // Test <character-string> that separated by space
+    CharacterString cstr2("foo bar");
+    EXPECT_EQ(string("foo"), cstr2.str());
+
+    // Test <character-string> that separated by quotes
+    CharacterString cstr3("\"foo bar\"");
+    EXPECT_EQ(string("foo bar"), cstr3.str());
+
+    // Test <character-string> that not separate by quotes but ended with quotes
+    CharacterString cstr4("foo\"");
+    EXPECT_EQ(string("foo\""), cstr4.str());
+}
+
+TEST_F(CharacterStringTest, testBadCase) {
+    // The <character-string> that started with quotes should also be ended
+    // with quotes
+    EXPECT_THROW(CharacterString cstr("\"foo"), InvalidRdataText);
+
+    // The string length cannot exceed 255 characters
+    string str;
+    for (int i = 0; i < 257; ++i) {
+        str += 'A';
+    }
+    EXPECT_THROW(CharacterString cstr(str), CharStringTooLong);
+}
+
+TEST_F(CharacterStringTest, testEscapeCharacter) {
+    CharacterString cstr1("foo\\bar");
+    EXPECT_EQ(string("foobar"), cstr1.str());
+
+    CharacterString cstr2("foo\\\\bar");
+    EXPECT_EQ(string("foo\\bar"), cstr2.str());
+
+    CharacterString cstr3("fo\\111bar");
+    EXPECT_EQ(string("foobar"), cstr3.str());
+
+    CharacterString cstr4("fo\\1112bar");
+    EXPECT_EQ(string("foo2bar"), cstr4.str());
+
+    // There must be at least 3 digits followed by '\'
+    EXPECT_THROW(CharacterString cstr("foo\\98ar"), InvalidRdataText);
+    EXPECT_THROW(CharacterString cstr("foo\\9ar"), InvalidRdataText);
+    EXPECT_THROW(CharacterString cstr("foo\\98"), InvalidRdataText);
+}
+
+} // namespace




More information about the bind10-changes mailing list