Upstream version 11.40.277.0
[platform/framework/web/crosswalk.git] / src / base / json / string_escape_unittest.cc
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/json/string_escape.h"
6
7 #include "base/strings/string_util.h"
8 #include "base/strings/utf_string_conversions.h"
9 #include "testing/gtest/include/gtest/gtest.h"
10
11 namespace base {
12
13 TEST(JSONStringEscapeTest, EscapeUTF8) {
14   const struct {
15     const char* to_escape;
16     const char* escaped;
17   } cases[] = {
18     {"\b\001aZ\"\\wee", "\\b\\u0001aZ\\\"\\\\wee"},
19     {"a\b\f\n\r\t\v\1\\.\"z",
20         "a\\b\\f\\n\\r\\t\\u000B\\u0001\\\\.\\\"z"},
21     {"b\x0f\x7f\xf0\xff!",  // \xf0\xff is not a valid UTF-8 unit.
22         "b\\u000F\x7F\xEF\xBF\xBD\xEF\xBF\xBD!"},
23     {"c<>d", "c\\u003C>d"},
24   };
25
26   for (size_t i = 0; i < arraysize(cases); ++i) {
27     const char* in_ptr = cases[i].to_escape;
28     std::string in_str = in_ptr;
29
30     std::string out;
31     EscapeJSONString(in_ptr, false, &out);
32     EXPECT_EQ(std::string(cases[i].escaped), out);
33     EXPECT_TRUE(IsStringUTF8(out));
34
35     out.erase();
36     bool convert_ok = EscapeJSONString(in_str, false, &out);
37     EXPECT_EQ(std::string(cases[i].escaped), out);
38     EXPECT_TRUE(IsStringUTF8(out));
39
40     if (convert_ok) {
41       std::string fooout = GetQuotedJSONString(in_str);
42       EXPECT_EQ("\"" + std::string(cases[i].escaped) + "\"", fooout);
43       EXPECT_TRUE(IsStringUTF8(out));
44     }
45   }
46
47   std::string in = cases[0].to_escape;
48   std::string out;
49   EscapeJSONString(in, false, &out);
50   EXPECT_TRUE(IsStringUTF8(out));
51
52   // test quoting
53   std::string out_quoted;
54   EscapeJSONString(in, true, &out_quoted);
55   EXPECT_EQ(out.length() + 2, out_quoted.length());
56   EXPECT_EQ(out_quoted.find(out), 1U);
57   EXPECT_TRUE(IsStringUTF8(out_quoted));
58
59   // now try with a NULL in the string
60   std::string null_prepend = "test";
61   null_prepend.push_back(0);
62   in = null_prepend + in;
63   std::string expected = "test\\u0000";
64   expected += cases[0].escaped;
65   out.clear();
66   EscapeJSONString(in, false, &out);
67   EXPECT_EQ(expected, out);
68   EXPECT_TRUE(IsStringUTF8(out));
69 }
70
71 TEST(JSONStringEscapeTest, EscapeUTF16) {
72   const struct {
73     const wchar_t* to_escape;
74     const char* escaped;
75   } cases[] = {
76     {L"b\uffb1\u00ff", "b\xEF\xBE\xB1\xC3\xBF"},
77     {L"\b\001aZ\"\\wee", "\\b\\u0001aZ\\\"\\\\wee"},
78     {L"a\b\f\n\r\t\v\1\\.\"z",
79         "a\\b\\f\\n\\r\\t\\u000B\\u0001\\\\.\\\"z"},
80     {L"b\x0f\x7f\xf0\xff!", "b\\u000F\x7F\xC3\xB0\xC3\xBF!"},
81     {L"c<>d", "c\\u003C>d"},
82   };
83
84   for (size_t i = 0; i < arraysize(cases); ++i) {
85     string16 in = WideToUTF16(cases[i].to_escape);
86
87     std::string out;
88     EscapeJSONString(in, false, &out);
89     EXPECT_EQ(std::string(cases[i].escaped), out);
90     EXPECT_TRUE(IsStringUTF8(out));
91
92     out = GetQuotedJSONString(in);
93     EXPECT_EQ("\"" + std::string(cases[i].escaped) + "\"", out);
94     EXPECT_TRUE(IsStringUTF8(out));
95   }
96
97   string16 in = WideToUTF16(cases[0].to_escape);
98   std::string out;
99   EscapeJSONString(in, false, &out);
100   EXPECT_TRUE(IsStringUTF8(out));
101
102   // test quoting
103   std::string out_quoted;
104   EscapeJSONString(in, true, &out_quoted);
105   EXPECT_EQ(out.length() + 2, out_quoted.length());
106   EXPECT_EQ(out_quoted.find(out), 1U);
107   EXPECT_TRUE(IsStringUTF8(out));
108
109   // now try with a NULL in the string
110   string16 null_prepend = WideToUTF16(L"test");
111   null_prepend.push_back(0);
112   in = null_prepend + in;
113   std::string expected = "test\\u0000";
114   expected += cases[0].escaped;
115   out.clear();
116   EscapeJSONString(in, false, &out);
117   EXPECT_EQ(expected, out);
118   EXPECT_TRUE(IsStringUTF8(out));
119 }
120
121 TEST(JSONStringEscapeTest, EscapeUTF16OutsideBMP) {
122   {
123     // {a, U+10300, !}, SMP.
124     string16 test;
125     test.push_back('a');
126     test.push_back(0xD800);
127     test.push_back(0xDF00);
128     test.push_back('!');
129     std::string actual;
130     EXPECT_TRUE(EscapeJSONString(test, false, &actual));
131     EXPECT_EQ("a\xF0\x90\x8C\x80!", actual);
132   }
133   {
134     // {U+20021, U+2002B}, SIP.
135     string16 test;
136     test.push_back(0xD840);
137     test.push_back(0xDC21);
138     test.push_back(0xD840);
139     test.push_back(0xDC2B);
140     std::string actual;
141     EXPECT_TRUE(EscapeJSONString(test, false, &actual));
142     EXPECT_EQ("\xF0\xA0\x80\xA1\xF0\xA0\x80\xAB", actual);
143   }
144   {
145     // {?, U+D800, @}, lone surrogate.
146     string16 test;
147     test.push_back('?');
148     test.push_back(0xD800);
149     test.push_back('@');
150     std::string actual;
151     EXPECT_FALSE(EscapeJSONString(test, false, &actual));
152     EXPECT_EQ("?\xEF\xBF\xBD@", actual);
153   }
154 }
155
156 TEST(JSONStringEscapeTest, EscapeBytes) {
157   const struct {
158     const char* to_escape;
159     const char* escaped;
160   } cases[] = {
161     {"b\x0f\x7f\xf0\xff!", "b\\u000F\\u007F\\u00F0\\u00FF!"},
162     {"\xe5\xc4\x4f\x05\xb6\xfd\0", "\\u00E5\\u00C4O\\u0005\\u00B6\\u00FD"},
163   };
164
165   for (size_t i = 0; i < arraysize(cases); ++i) {
166     std::string in = std::string(cases[i].to_escape);
167     EXPECT_FALSE(IsStringUTF8(in));
168
169     EXPECT_EQ(std::string(cases[i].escaped),
170         EscapeBytesAsInvalidJSONString(in, false));
171     EXPECT_EQ("\"" + std::string(cases[i].escaped) + "\"",
172         EscapeBytesAsInvalidJSONString(in, true));
173   }
174
175   const char kEmbedNull[] = { '\xab', '\x39', '\0', '\x9f', '\xab' };
176   std::string in(kEmbedNull, arraysize(kEmbedNull));
177   EXPECT_FALSE(IsStringUTF8(in));
178   EXPECT_EQ(std::string("\\u00AB9\\u0000\\u009F\\u00AB"),
179             EscapeBytesAsInvalidJSONString(in, false));
180 }
181
182 }  // namespace base