]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#3086] add support for \0 in eval parser
authorRazvan Becheriu <razvan@isc.org>
Fri, 22 Sep 2023 17:49:48 +0000 (20:49 +0300)
committerRazvan Becheriu <razvan@isc.org>
Fri, 6 Oct 2023 09:02:15 +0000 (09:02 +0000)
src/lib/eval/lexer.cc
src/lib/eval/lexer.ll
src/lib/eval/tests/context_unittest.cc
src/lib/eval/tests/token_unittest.cc

index 212587242b8899ea21df5980ab055e6cda9d4dc2..11cd4a33f0f4051282c1529639cb24f483b88be0 100644 (file)
@@ -991,13 +991,13 @@ int yy_flex_debug = 1;
 
 static const flex_int16_t yy_rule_linenum[65] =
     {   0,
-      107,  112,  118,  128,  134,  152,  176,  190,  191,  192,
-      193,  194,  195,  196,  197,  198,  199,  200,  201,  202,
-      203,  204,  205,  206,  207,  208,  209,  210,  211,  212,
-      213,  214,  215,  216,  217,  218,  219,  220,  221,  222,
-      223,  224,  225,  226,  227,  228,  229,  230,  231,  232,
-      233,  234,  235,  236,  237,  238,  239,  240,  241,  242,
-      243,  244,  245,  246
+      107,  112,  118,  127,  133,  151,  175,  189,  190,  191,
+      192,  193,  194,  195,  196,  197,  198,  199,  200,  201,
+      202,  203,  204,  205,  206,  207,  208,  209,  210,  211,
+      212,  213,  214,  215,  216,  217,  218,  219,  220,  221,
+      222,  223,  224,  225,  226,  227,  228,  229,  230,  231,
+      232,  233,  234,  235,  236,  237,  238,  239,  240,  241,
+      242,  243,  244,  245
     } ;
 
 /* The intent behind this definition is that it'll catch
@@ -1485,15 +1485,14 @@ YY_RULE_SETUP
     /* A string has been matched. It contains the actual string and single quotes.
        We need to get those quotes out of the way and just use its content, e.g.
        for 'foo' we should get foo */
-    std::string tmp(evaltext+1);
-    tmp.resize(tmp.size() - 1);
+    std::string tmp(evaltext+1, evalleng-2);
 
     return isc::eval::EvalParser::make_STRING(tmp, loc);
 }
        YY_BREAK
 case 4:
 YY_RULE_SETUP
-#line 128 "lexer.ll"
+#line 127 "lexer.ll"
 {
     /* A hex string has been matched. It contains the '0x' or '0X' header
        followed by at least one hexadecimal digit. */
@@ -1502,7 +1501,7 @@ YY_RULE_SETUP
        YY_BREAK
 case 5:
 YY_RULE_SETUP
-#line 134 "lexer.ll"
+#line 133 "lexer.ll"
 {
     /* An integer was found. */
     std::string tmp(evaltext);
@@ -1528,7 +1527,7 @@ YY_LINENO_REWIND_TO(yy_cp - 1);
 (yy_c_buf_p) = yy_cp -= 1;
 YY_DO_BEFORE_ACTION; /* set up yytext again */
 YY_RULE_SETUP
-#line 152 "lexer.ll"
+#line 151 "lexer.ll"
 {
     /* This string specifies option name starting with a letter
        and further containing letters, digits, hyphens and
@@ -1555,7 +1554,7 @@ YY_RULE_SETUP
        YY_BREAK
 case 7:
 YY_RULE_SETUP
-#line 176 "lexer.ll"
+#line 175 "lexer.ll"
 {
     /* IPv4 or IPv6 address */
     std::string tmp(evaltext);
@@ -1572,296 +1571,296 @@ YY_RULE_SETUP
        YY_BREAK
 case 8:
 YY_RULE_SETUP
-#line 190 "lexer.ll"
+#line 189 "lexer.ll"
 return isc::eval::EvalParser::make_EQUAL(loc);
        YY_BREAK
 case 9:
 YY_RULE_SETUP
-#line 191 "lexer.ll"
+#line 190 "lexer.ll"
 return isc::eval::EvalParser::make_OPTION(loc);
        YY_BREAK
 case 10:
 YY_RULE_SETUP
-#line 192 "lexer.ll"
+#line 191 "lexer.ll"
 return isc::eval::EvalParser::make_RELAY4(loc);
        YY_BREAK
 case 11:
 YY_RULE_SETUP
-#line 193 "lexer.ll"
+#line 192 "lexer.ll"
 return isc::eval::EvalParser::make_RELAY6(loc);
        YY_BREAK
 case 12:
 YY_RULE_SETUP
-#line 194 "lexer.ll"
+#line 193 "lexer.ll"
 return isc::eval::EvalParser::make_PEERADDR(loc);
        YY_BREAK
 case 13:
 YY_RULE_SETUP
-#line 195 "lexer.ll"
+#line 194 "lexer.ll"
 return isc::eval::EvalParser::make_LINKADDR(loc);
        YY_BREAK
 case 14:
 YY_RULE_SETUP
-#line 196 "lexer.ll"
+#line 195 "lexer.ll"
 return isc::eval::EvalParser::make_TEXT(loc);
        YY_BREAK
 case 15:
 YY_RULE_SETUP
-#line 197 "lexer.ll"
+#line 196 "lexer.ll"
 return isc::eval::EvalParser::make_HEX(loc);
        YY_BREAK
 case 16:
 YY_RULE_SETUP
-#line 198 "lexer.ll"
+#line 197 "lexer.ll"
 return isc::eval::EvalParser::make_EXISTS(loc);
        YY_BREAK
 case 17:
 YY_RULE_SETUP
-#line 199 "lexer.ll"
+#line 198 "lexer.ll"
 return isc::eval::EvalParser::make_PKT(loc);
        YY_BREAK
 case 18:
 YY_RULE_SETUP
-#line 200 "lexer.ll"
+#line 199 "lexer.ll"
 return isc::eval::EvalParser::make_IFACE(loc);
        YY_BREAK
 case 19:
 YY_RULE_SETUP
-#line 201 "lexer.ll"
+#line 200 "lexer.ll"
 return isc::eval::EvalParser::make_SRC(loc);
        YY_BREAK
 case 20:
 YY_RULE_SETUP
-#line 202 "lexer.ll"
+#line 201 "lexer.ll"
 return isc::eval::EvalParser::make_DST(loc);
        YY_BREAK
 case 21:
 YY_RULE_SETUP
-#line 203 "lexer.ll"
+#line 202 "lexer.ll"
 return isc::eval::EvalParser::make_LEN(loc);
        YY_BREAK
 case 22:
 YY_RULE_SETUP
-#line 204 "lexer.ll"
+#line 203 "lexer.ll"
 return isc::eval::EvalParser::make_PKT4(loc);
        YY_BREAK
 case 23:
 YY_RULE_SETUP
-#line 205 "lexer.ll"
+#line 204 "lexer.ll"
 return isc::eval::EvalParser::make_CHADDR(loc);
        YY_BREAK
 case 24:
 YY_RULE_SETUP
-#line 206 "lexer.ll"
+#line 205 "lexer.ll"
 return isc::eval::EvalParser::make_HLEN(loc);
        YY_BREAK
 case 25:
 YY_RULE_SETUP
-#line 207 "lexer.ll"
+#line 206 "lexer.ll"
 return isc::eval::EvalParser::make_HTYPE(loc);
        YY_BREAK
 case 26:
 YY_RULE_SETUP
-#line 208 "lexer.ll"
+#line 207 "lexer.ll"
 return isc::eval::EvalParser::make_CIADDR(loc);
        YY_BREAK
 case 27:
 YY_RULE_SETUP
-#line 209 "lexer.ll"
+#line 208 "lexer.ll"
 return isc::eval::EvalParser::make_GIADDR(loc);
        YY_BREAK
 case 28:
 YY_RULE_SETUP
-#line 210 "lexer.ll"
+#line 209 "lexer.ll"
 return isc::eval::EvalParser::make_YIADDR(loc);
        YY_BREAK
 case 29:
 YY_RULE_SETUP
-#line 211 "lexer.ll"
+#line 210 "lexer.ll"
 return isc::eval::EvalParser::make_SIADDR(loc);
        YY_BREAK
 case 30:
 YY_RULE_SETUP
-#line 212 "lexer.ll"
+#line 211 "lexer.ll"
 return isc::eval::EvalParser::make_PKT6(loc);
        YY_BREAK
 case 31:
 YY_RULE_SETUP
-#line 213 "lexer.ll"
+#line 212 "lexer.ll"
 return isc::eval::EvalParser::make_MSGTYPE(loc);
        YY_BREAK
 case 32:
 YY_RULE_SETUP
-#line 214 "lexer.ll"
+#line 213 "lexer.ll"
 return isc::eval::EvalParser::make_TRANSID(loc);
        YY_BREAK
 case 33:
 YY_RULE_SETUP
-#line 215 "lexer.ll"
+#line 214 "lexer.ll"
 return isc::eval::EvalParser::make_VENDOR(loc);
        YY_BREAK
 case 34:
 YY_RULE_SETUP
-#line 216 "lexer.ll"
+#line 215 "lexer.ll"
 return isc::eval::EvalParser::make_VENDOR_CLASS(loc);
        YY_BREAK
 case 35:
 YY_RULE_SETUP
-#line 217 "lexer.ll"
+#line 216 "lexer.ll"
 return isc::eval::EvalParser::make_DATA(loc);
        YY_BREAK
 case 36:
 YY_RULE_SETUP
-#line 218 "lexer.ll"
+#line 217 "lexer.ll"
 return isc::eval::EvalParser::make_ENTERPRISE(loc);
        YY_BREAK
 case 37:
 YY_RULE_SETUP
-#line 219 "lexer.ll"
+#line 218 "lexer.ll"
 return isc::eval::EvalParser::make_SUBSTRING(loc);
        YY_BREAK
 case 38:
 YY_RULE_SETUP
-#line 220 "lexer.ll"
+#line 219 "lexer.ll"
 return isc::eval::EvalParser::make_LCASE(loc);
        YY_BREAK
 case 39:
 YY_RULE_SETUP
-#line 221 "lexer.ll"
+#line 220 "lexer.ll"
 return isc::eval::EvalParser::make_UCASE(loc);
        YY_BREAK
 case 40:
 YY_RULE_SETUP
-#line 222 "lexer.ll"
+#line 221 "lexer.ll"
 return isc::eval::EvalParser::make_SPLIT(loc);
        YY_BREAK
 case 41:
 YY_RULE_SETUP
-#line 223 "lexer.ll"
+#line 222 "lexer.ll"
 return isc::eval::EvalParser::make_ALL(loc);
        YY_BREAK
 case 42:
 YY_RULE_SETUP
-#line 224 "lexer.ll"
+#line 223 "lexer.ll"
 return isc::eval::EvalParser::make_CONCAT(loc);
        YY_BREAK
 case 43:
 YY_RULE_SETUP
-#line 225 "lexer.ll"
+#line 224 "lexer.ll"
 return isc::eval::EvalParser::make_IFELSE(loc);
        YY_BREAK
 case 44:
 YY_RULE_SETUP
-#line 226 "lexer.ll"
+#line 225 "lexer.ll"
 return isc::eval::EvalParser::make_TOHEXSTRING(loc);
        YY_BREAK
 case 45:
 YY_RULE_SETUP
-#line 227 "lexer.ll"
+#line 226 "lexer.ll"
 return isc::eval::EvalParser::make_ADDRTOTEXT(loc);
        YY_BREAK
 case 46:
 YY_RULE_SETUP
-#line 228 "lexer.ll"
+#line 227 "lexer.ll"
 return isc::eval::EvalParser::make_INT8TOTEXT(loc);
        YY_BREAK
 case 47:
 YY_RULE_SETUP
-#line 229 "lexer.ll"
+#line 228 "lexer.ll"
 return isc::eval::EvalParser::make_INT16TOTEXT(loc);
        YY_BREAK
 case 48:
 YY_RULE_SETUP
-#line 230 "lexer.ll"
+#line 229 "lexer.ll"
 return isc::eval::EvalParser::make_INT32TOTEXT(loc);
        YY_BREAK
 case 49:
 YY_RULE_SETUP
-#line 231 "lexer.ll"
+#line 230 "lexer.ll"
 return isc::eval::EvalParser::make_UINT8TOTEXT(loc);
        YY_BREAK
 case 50:
 YY_RULE_SETUP
-#line 232 "lexer.ll"
+#line 231 "lexer.ll"
 return isc::eval::EvalParser::make_UINT16TOTEXT(loc);
        YY_BREAK
 case 51:
 YY_RULE_SETUP
-#line 233 "lexer.ll"
+#line 232 "lexer.ll"
 return isc::eval::EvalParser::make_UINT32TOTEXT(loc);
        YY_BREAK
 case 52:
 YY_RULE_SETUP
-#line 234 "lexer.ll"
+#line 233 "lexer.ll"
 return isc::eval::EvalParser::make_NOT(loc);
        YY_BREAK
 case 53:
 YY_RULE_SETUP
-#line 235 "lexer.ll"
+#line 234 "lexer.ll"
 return isc::eval::EvalParser::make_AND(loc);
        YY_BREAK
 case 54:
 YY_RULE_SETUP
-#line 236 "lexer.ll"
+#line 235 "lexer.ll"
 return isc::eval::EvalParser::make_OR(loc);
        YY_BREAK
 case 55:
 YY_RULE_SETUP
-#line 237 "lexer.ll"
+#line 236 "lexer.ll"
 return isc::eval::EvalParser::make_MEMBER(loc);
        YY_BREAK
 case 56:
 YY_RULE_SETUP
-#line 238 "lexer.ll"
+#line 237 "lexer.ll"
 return isc::eval::EvalParser::make_DOT(loc);
        YY_BREAK
 case 57:
 YY_RULE_SETUP
-#line 239 "lexer.ll"
+#line 238 "lexer.ll"
 return isc::eval::EvalParser::make_LPAREN(loc);
        YY_BREAK
 case 58:
 YY_RULE_SETUP
-#line 240 "lexer.ll"
+#line 239 "lexer.ll"
 return isc::eval::EvalParser::make_RPAREN(loc);
        YY_BREAK
 case 59:
 YY_RULE_SETUP
-#line 241 "lexer.ll"
+#line 240 "lexer.ll"
 return isc::eval::EvalParser::make_LBRACKET(loc);
        YY_BREAK
 case 60:
 YY_RULE_SETUP
-#line 242 "lexer.ll"
+#line 241 "lexer.ll"
 return isc::eval::EvalParser::make_RBRACKET(loc);
        YY_BREAK
 case 61:
 YY_RULE_SETUP
-#line 243 "lexer.ll"
+#line 242 "lexer.ll"
 return isc::eval::EvalParser::make_COMA(loc);
        YY_BREAK
 case 62:
 YY_RULE_SETUP
-#line 244 "lexer.ll"
+#line 243 "lexer.ll"
 return isc::eval::EvalParser::make_ANY(loc);
        YY_BREAK
 case 63:
 YY_RULE_SETUP
-#line 245 "lexer.ll"
+#line 244 "lexer.ll"
 return isc::eval::EvalParser::make_PLUS(loc);
        YY_BREAK
 case 64:
 YY_RULE_SETUP
-#line 246 "lexer.ll"
+#line 245 "lexer.ll"
 driver.error (loc, "Invalid character: " + std::string(evaltext));
        YY_BREAK
 case YY_STATE_EOF(INITIAL):
-#line 247 "lexer.ll"
+#line 246 "lexer.ll"
 return isc::eval::EvalParser::make_END(loc);
        YY_BREAK
 case 65:
 YY_RULE_SETUP
-#line 248 "lexer.ll"
+#line 247 "lexer.ll"
 ECHO;
        YY_BREAK
 #line 1867 "lexer.cc"
@@ -2976,7 +2975,7 @@ void yyfree (void * ptr )
 
 /* %ok-for-header */
 
-#line 248 "lexer.ll"
+#line 247 "lexer.ll"
 
 
 using namespace isc::eval;
index 27fcef9971dcfb836d889f703749a2b586e91c41..542557408dcd2498d18d45596f1059d783704494 100644 (file)
@@ -118,8 +118,7 @@ addr6 [0-9a-fA-F]*\:[0-9a-fA-F]*\:[0-9a-fA-F:.]*
     /* A string has been matched. It contains the actual string and single quotes.
        We need to get those quotes out of the way and just use its content, e.g.
        for 'foo' we should get foo */
-    std::string tmp(evaltext+1);
-    tmp.resize(tmp.size() - 1);
+    std::string tmp(evaltext+1, evalleng-2);
 
     return isc::eval::EvalParser::make_STRING(tmp, loc);
 }
index 2b511c4d0a85862f20923da9cb446b125e453764..4e75a31c935545d38e8d913b5951a8adf26723bc 100644 (file)
@@ -854,9 +854,32 @@ TEST_F(EvalContextTest, string) {
 
     TokenPtr tmp1  = eval.expression.at(0);
     TokenPtr tmp2  = eval.expression.at(1);
+    TokenPtr tmp3  = eval.expression.at(2);
 
     checkTokenString(tmp1, "foo");
     checkTokenString(tmp2, "bar");
+    checkTokenEq(tmp3);
+}
+
+// Test the parsing of a string terminal
+TEST_F(EvalContextTest, stringComplex) {
+    EvalContext eval(Option::V4);
+
+    char data[] = "'12345~!@#$%^&*()_+{}[];:<>/?\\67890\t \0\b\r\f' == 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'";
+    EXPECT_NO_THROW(parsed_ = eval.parseString(string(data, sizeof(data) - 1)));
+    EXPECT_TRUE(parsed_);
+
+    ASSERT_EQ(3, eval.expression.size());
+
+    TokenPtr tmp1  = eval.expression.at(0);
+    TokenPtr tmp2  = eval.expression.at(1);
+    TokenPtr tmp3  = eval.expression.at(2);
+
+    char l_data[] = "12345~!@#$%^&*()_+{}[];:<>/?\\67890\t \0\b\r\f";
+    char r_data[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+    checkTokenString(tmp1, string(l_data, sizeof(l_data) - 1));
+    checkTokenString(tmp2, string(r_data, sizeof(r_data) - 1));
+    checkTokenEq(tmp3);
 }
 
 // Test the parsing of a basic expression using integers
@@ -864,8 +887,7 @@ TEST_F(EvalContextTest, integer) {
 
     EvalContext eval(Option::V4);
 
-    EXPECT_NO_THROW(parsed_ =
-        eval.parseString("substring(option[123].text, 0, 2) == '42'"));
+    EXPECT_NO_THROW(parsed_ = eval.parseString("substring(option[123].text, 0, 2) == '42'"));
     EXPECT_TRUE(parsed_);
 }
 
@@ -1572,8 +1594,9 @@ TEST_F(EvalContextTest, lcase) {
 TEST_F(EvalContextTest, lcaseComplex) {
     EvalContext eval(Option::V4);
 
-    EXPECT_NO_THROW(parsed_ = eval.parseString("lcase('12345~!@#$%^&*()_+LoWeR{}[];:<>/?\\67890\t \b\r\f') == "
-                                               "'12345~!@#$%^&*()_+lower{}[];:<>/?\\67890\t \b\r\f'"));
+    char data[] = "lcase('12345~!@#$%^&*()_+LoWeR{}[];:<>/?\\67890\t \0\b\r\f') == "
+                  "'12345~!@#$%^&*()_+lower{}[];:<>/?\\67890\t \0\b\r\f'";
+    EXPECT_NO_THROW(parsed_ = eval.parseString(string(data, sizeof(data) - 1)));
     EXPECT_TRUE(parsed_);
 
     ASSERT_EQ(4, eval.expression.size());
@@ -1583,9 +1606,11 @@ TEST_F(EvalContextTest, lcaseComplex) {
     TokenPtr tmp3 = eval.expression.at(2);
     TokenPtr tmp4 = eval.expression.at(3);
 
-    checkTokenString(tmp1, "12345~!@#$%^&*()_+LoWeR{}[];:<>/?\\67890\t \b\r\f");
-    checkTokenLowerCase(tmp2, "12345~!@#$%^&*()_+lower{}[];:<>/?\\67890\t \b\r\f");
-    checkTokenString(tmp3, "12345~!@#$%^&*()_+lower{}[];:<>/?\\67890\t \b\r\f");
+    char expected_data[] = "12345~!@#$%^&*()_+LoWeR{}[];:<>/?\\67890\t \0\b\r\f";
+    char expected_updated_data[] = "12345~!@#$%^&*()_+lower{}[];:<>/?\\67890\t \0\b\r\f";
+    checkTokenString(tmp1, string(expected_data, sizeof(expected_data) - 1));
+    checkTokenLowerCase(tmp2, string(expected_updated_data, sizeof(expected_updated_data) - 1));
+    checkTokenString(tmp3, string(expected_updated_data, sizeof(expected_updated_data) - 1));
     checkTokenEq(tmp4);
 }
 
@@ -1613,8 +1638,9 @@ TEST_F(EvalContextTest, ucase) {
 TEST_F(EvalContextTest, ucaseComplex) {
     EvalContext eval(Option::V4);
 
-    EXPECT_NO_THROW(parsed_ = eval.parseString("ucase('12345~!@#$%^&*()_+uPpEr{}[];:<>/?\\67890\t \b\r\f') == "
-                                               "'12345~!@#$%^&*()_+UPPER{}[];:<>/?\\67890\t \b\r\f'"));
+    char data[] = "ucase('12345~!@#$%^&*()_+uPpEr{}[];:<>/?\\67890\t \0\b\r\f') == "
+                  "'12345~!@#$%^&*()_+UPPER{}[];:<>/?\\67890\t \0\b\r\f'";
+    EXPECT_NO_THROW(parsed_ = eval.parseString(string(data, sizeof(data) - 1)));
     EXPECT_TRUE(parsed_);
 
     ASSERT_EQ(4, eval.expression.size());
@@ -1624,9 +1650,11 @@ TEST_F(EvalContextTest, ucaseComplex) {
     TokenPtr tmp3 = eval.expression.at(2);
     TokenPtr tmp4 = eval.expression.at(3);
 
-    checkTokenString(tmp1, "12345~!@#$%^&*()_+uPpEr{}[];:<>/?\\67890\t \b\r\f");
-    checkTokenUpperCase(tmp2, "12345~!@#$%^&*()_+UPPER{}[];:<>/?\\67890\t \b\r\f");
-    checkTokenString(tmp3, "12345~!@#$%^&*()_+UPPER{}[];:<>/?\\67890\t \b\r\f");
+    char expected_data[] = "12345~!@#$%^&*()_+uPpEr{}[];:<>/?\\67890\t \0\b\r\f";
+    char expected_updated_data[] = "12345~!@#$%^&*()_+UPPER{}[];:<>/?\\67890\t \0\b\r\f";
+    checkTokenString(tmp1, string(expected_data, sizeof(expected_data) - 1));
+    checkTokenUpperCase(tmp2, string(expected_updated_data, sizeof(expected_updated_data) - 1));
+    checkTokenString(tmp3, string(expected_updated_data, sizeof(expected_updated_data) - 1));
     checkTokenEq(tmp4);
 }
 
index b01e238384b84df734101eb5210829a5d0fe1034..2ef7a32a1a6ce2406e071100d807ebf24c95fa4f 100644 (file)
@@ -589,6 +589,30 @@ TEST_F(TokenTest, string4) {
     EXPECT_TRUE(checkFile());
 }
 
+// This simple test checks that a TokenString, representing a constant string,
+// can be used in Pkt4 evaluation. (The actual packet is not used)
+TEST_F(TokenTest, string4Complex) {
+    char data[] = "12345~!@#$%^&*()_+{}[];:<>/?\\67890\t \0\b\r\f'\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+    string data_str(data, sizeof(data) - 1);
+    // Store constant string in the TokenString object.
+    ASSERT_NO_THROW(t_.reset(new TokenString(data_str)));
+
+    // Make sure that the token can be evaluated without exceptions.
+    ASSERT_NO_THROW(t_->evaluate(*pkt4_, values_));
+
+    // Check that the evaluation put its value on the values stack.
+    ASSERT_EQ(1, values_.size());
+    EXPECT_EQ(data_str, values_.top());
+
+    // Check that the debug output was correct.  Add the strings
+    // to the test vector in the class and then call checkFile
+    // for comparison
+    char expected[] = "EVAL_DEBUG_STRING Pushing text string '12345~!@#$%^&*()_+{}[];:<>/?\\67890\t \0\b\r\f'\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'";
+    string expected_str(expected, sizeof(expected) - 1);
+    addString(expected_str);
+    EXPECT_TRUE(checkFile());
+}
+
 // This simple test checks that a TokenString, representing a constant string,
 // can be used in Pkt6 evaluation. (The actual packet is not used)
 TEST_F(TokenTest, string6) {
@@ -610,6 +634,30 @@ TEST_F(TokenTest, string6) {
     EXPECT_TRUE(checkFile());
 }
 
+// This simple test checks that a TokenString, representing a constant string,
+// can be used in Pkt6 evaluation. (The actual packet is not used)
+TEST_F(TokenTest, string6Complex) {
+    char data[] = "12345~!@#$%^&*()_+{}[];:<>/?\\67890\t \0\b\r\f'\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+    string data_str(data, sizeof(data) - 1);
+    // Store constant string in the TokenString object.
+    ASSERT_NO_THROW(t_.reset(new TokenString(data_str)));
+
+    // Make sure that the token can be evaluated without exceptions.
+    ASSERT_NO_THROW(t_->evaluate(*pkt6_, values_));
+
+    // Check that the evaluation put its value on the values stack.
+    ASSERT_EQ(1, values_.size());
+    EXPECT_EQ(data_str, values_.top());
+
+    // Check that the debug output was correct.  Add the strings
+    // to the test vector in the class and then call checkFile
+    // for comparison
+    char expected[] = "EVAL_DEBUG_STRING Pushing text string '12345~!@#$%^&*()_+{}[];:<>/?\\67890\t \0\b\r\f'\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'";
+    string expected_str(expected, sizeof(expected) - 1);
+    addString(expected_str);
+    EXPECT_TRUE(checkFile());
+}
+
 // This simple test checks that a TokenHexString, representing a constant
 // string coded in hexadecimal, can be used in Pkt4 evaluation.
 // (The actual packet is not used)
@@ -771,20 +819,26 @@ TEST_F(TokenTest, lcase) {
 // is not used)
 TEST_F(TokenTest, lcaseComplex) {
     ASSERT_NO_THROW(t_.reset(new TokenLowerCase()));
-    values_.push("12345~!@#$%^&*()_+LoWeR{}[];:<>/?\\67890\t \b\r\f");
+    char data[] = "12345~!@#$%^&*()_+LoWeR{}[];:<>/?\\67890\t \0\b\r\f";
+    string data_str(data, sizeof(data) - 1);
+    values_.push(data_str);
 
     // Make sure that the token can be evaluated without exceptions.
     ASSERT_NO_THROW(t_->evaluate(*pkt6_, values_));
 
     // Check that the evaluation put its value on the values stack.
     ASSERT_EQ(1, values_.size());
-    EXPECT_EQ("12345~!@#$%^&*()_+lower{}[];:<>/?\\67890\t \b\r\f", values_.top());
+    char expected_data[] = "12345~!@#$%^&*()_+lower{}[];:<>/?\\67890\t \0\b\r\f";
+    string expected_data_str(expected_data, sizeof(expected_data) - 1);
+    EXPECT_EQ(expected_data_str, values_.top());
 
     // Check that the debug output was correct.  Add the strings
     // to the test vector in the class and then call checkFile
     // for comparison
-    addString("EVAL_DEBUG_LCASE Poping string '12345~!@#$%^&*()_+LoWeR{}[];:<>/?\\67890\t \b\r\f' "
-              "and pushing converted value to lower case '12345~!@#$%^&*()_+lower{}[];:<>/?\\67890\t \b\r\f'");
+    char expected[] = "EVAL_DEBUG_LCASE Poping string '12345~!@#$%^&*()_+LoWeR{}[];:<>/?\\67890\t \0\b\r\f' "
+                      "and pushing converted value to lower case '12345~!@#$%^&*()_+lower{}[];:<>/?\\67890\t \0\b\r\f'";
+    string expected_str(expected, sizeof(expected) - 1);
+    addString(expected_str);
     EXPECT_TRUE(checkFile());
 }
 
@@ -814,20 +868,26 @@ TEST_F(TokenTest, ucase) {
 // is not used)
 TEST_F(TokenTest, ucaseComplex) {
     ASSERT_NO_THROW(t_.reset(new TokenUpperCase()));
-    values_.push("12345~!@#$%^&*()_+uPpEr{}[];:<>/?\\67890\t \b\r\f");
+    char data[] = "12345~!@#$%^&*()_+uPpEr{}[];:<>/?\\67890\t \0\b\r\f";
+    string data_str(data, sizeof(data) - 1);
+    values_.push(data_str);
 
     // Make sure that the token can be evaluated without exceptions.
     ASSERT_NO_THROW(t_->evaluate(*pkt6_, values_));
 
     // Check that the evaluation put its value on the values stack.
     ASSERT_EQ(1, values_.size());
-    EXPECT_EQ("12345~!@#$%^&*()_+UPPER{}[];:<>/?\\67890\t \b\r\f", values_.top());
+    char expected_data[] = "12345~!@#$%^&*()_+UPPER{}[];:<>/?\\67890\t \0\b\r\f";
+    string expected_data_str(expected_data, sizeof(expected_data) - 1);
+    EXPECT_EQ(expected_data_str, values_.top());
 
     // Check that the debug output was correct.  Add the strings
     // to the test vector in the class and then call checkFile
     // for comparison
-    addString("EVAL_DEBUG_UCASE Poping string '12345~!@#$%^&*()_+uPpEr{}[];:<>/?\\67890\t \b\r\f' "
-              "and pushing converted value to upper case '12345~!@#$%^&*()_+UPPER{}[];:<>/?\\67890\t \b\r\f'");
+    char expected[] = "EVAL_DEBUG_UCASE Poping string '12345~!@#$%^&*()_+uPpEr{}[];:<>/?\\67890\t \0\b\r\f' "
+                      "and pushing converted value to upper case '12345~!@#$%^&*()_+UPPER{}[];:<>/?\\67890\t \0\b\r\f'";
+    string expected_str(expected, sizeof(expected) - 1);
+    addString(expected_str);
     EXPECT_TRUE(checkFile());
 }