blob: 615acc411eef37cdd47c63758a8f18e0cdf69d2b [file] [log] [blame]
Vitaly Bukacbed2062015-08-17 12:54:05 -07001// 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
Vitaly Buka8750b272015-08-18 18:39:08 -07007#include <gtest/gtest.h>
8
Vitaly Bukacbed2062015-08-17 12:54:05 -07009#include "base/strings/string_util.h"
Vitaly Buka8750b272015-08-18 18:39:08 -070010#include "base/strings/utf_string_conversion_utils.h"
Vitaly Bukacbed2062015-08-17 12:54:05 -070011
12namespace base {
13
14TEST(JSONStringEscapeTest, EscapeUTF8) {
15 const struct {
16 const char* to_escape;
17 const char* escaped;
18 } cases[] = {
19 {"\b\001aZ\"\\wee", "\\b\\u0001aZ\\\"\\\\wee"},
20 {"a\b\f\n\r\t\v\1\\.\"z",
21 "a\\b\\f\\n\\r\\t\\u000B\\u0001\\\\.\\\"z"},
22 {"b\x0f\x7f\xf0\xff!", // \xf0\xff is not a valid UTF-8 unit.
23 "b\\u000F\x7F\xEF\xBF\xBD\xEF\xBF\xBD!"},
24 {"c<>d", "c\\u003C>d"},
25 };
26
27 for (size_t i = 0; i < arraysize(cases); ++i) {
28 const char* in_ptr = cases[i].to_escape;
29 std::string in_str = in_ptr;
30
31 std::string out;
32 EscapeJSONString(in_ptr, false, &out);
33 EXPECT_EQ(std::string(cases[i].escaped), out);
34 EXPECT_TRUE(IsStringUTF8(out));
35
36 out.erase();
37 bool convert_ok = EscapeJSONString(in_str, false, &out);
38 EXPECT_EQ(std::string(cases[i].escaped), out);
39 EXPECT_TRUE(IsStringUTF8(out));
40
41 if (convert_ok) {
42 std::string fooout = GetQuotedJSONString(in_str);
43 EXPECT_EQ("\"" + std::string(cases[i].escaped) + "\"", fooout);
44 EXPECT_TRUE(IsStringUTF8(out));
45 }
46 }
47
48 std::string in = cases[0].to_escape;
49 std::string out;
50 EscapeJSONString(in, false, &out);
51 EXPECT_TRUE(IsStringUTF8(out));
52
53 // test quoting
54 std::string out_quoted;
55 EscapeJSONString(in, true, &out_quoted);
56 EXPECT_EQ(out.length() + 2, out_quoted.length());
57 EXPECT_EQ(out_quoted.find(out), 1U);
58 EXPECT_TRUE(IsStringUTF8(out_quoted));
59
60 // now try with a NULL in the string
61 std::string null_prepend = "test";
62 null_prepend.push_back(0);
63 in = null_prepend + in;
64 std::string expected = "test\\u0000";
65 expected += cases[0].escaped;
66 out.clear();
67 EscapeJSONString(in, false, &out);
68 EXPECT_EQ(expected, out);
69 EXPECT_TRUE(IsStringUTF8(out));
70}
71
Vitaly Bukacbed2062015-08-17 12:54:05 -070072TEST(JSONStringEscapeTest, EscapeBytes) {
73 const struct {
74 const char* to_escape;
75 const char* escaped;
76 } cases[] = {
77 {"b\x0f\x7f\xf0\xff!", "b\\u000F\\u007F\\u00F0\\u00FF!"},
78 {"\xe5\xc4\x4f\x05\xb6\xfd", "\\u00E5\\u00C4O\\u0005\\u00B6\\u00FD"},
79 };
80
81 for (size_t i = 0; i < arraysize(cases); ++i) {
82 std::string in = std::string(cases[i].to_escape);
83 EXPECT_FALSE(IsStringUTF8(in));
84
85 EXPECT_EQ(std::string(cases[i].escaped),
86 EscapeBytesAsInvalidJSONString(in, false));
87 EXPECT_EQ("\"" + std::string(cases[i].escaped) + "\"",
88 EscapeBytesAsInvalidJSONString(in, true));
89 }
90
91 const char kEmbedNull[] = { '\xab', '\x39', '\0', '\x9f', '\xab' };
92 std::string in(kEmbedNull, arraysize(kEmbedNull));
93 EXPECT_FALSE(IsStringUTF8(in));
94 EXPECT_EQ(std::string("\\u00AB9\\u0000\\u009F\\u00AB"),
95 EscapeBytesAsInvalidJSONString(in, false));
96}
97
98} // namespace base