diff options
author | antrim@chromium.org <antrim@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-12-11 11:52:22 +0000 |
---|---|---|
committer | antrim@chromium.org <antrim@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-12-11 11:52:22 +0000 |
commit | 11b366da9588a954343196434e00822aa3cf9b93 (patch) | |
tree | 0c8d3d6b521be4308c4f979ad19e1526ca65bc8e | |
parent | 3fa8fe590f29d504ce1284d5b4814c64861b4ab7 (diff) | |
download | chromium_src-11b366da9588a954343196434e00822aa3cf9b93.zip chromium_src-11b366da9588a954343196434e00822aa3cf9b93.tar.gz chromium_src-11b366da9588a954343196434e00822aa3cf9b93.tar.bz2 |
Revert of https://codereview.chromium.org/100823007/
Reason for revert: This patchset breaks at least displayment of Russian localized strings on Chromeos login screen.
TBR=mark@chromium.org,jshin@chromium.org,thakis@chromium.org,asanka@chromium.org,zea@chromium.org,bauerb@chromium.org,rsesek@chromium.org
NOTREECHECKS=true
NOTRY=true
Review URL: https://codereview.chromium.org/106793004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@240082 0039d316-1c4b-4281-b951-d872f2087c98
26 files changed, 231 insertions, 342 deletions
diff --git a/base/debug/trace_event_impl.cc b/base/debug/trace_event_impl.cc index f9ff510..50bf342 100644 --- a/base/debug/trace_event_impl.cc +++ b/base/debug/trace_event_impl.cc @@ -662,7 +662,7 @@ void TraceEvent::AppendValueAsJSON(unsigned char type, break; case TRACE_VALUE_TYPE_STRING: case TRACE_VALUE_TYPE_COPY_STRING: - EscapeJSONString(value.as_string ? value.as_string : "NULL", true, out); + JsonDoubleQuote(value.as_string ? value.as_string : "NULL", true, out); break; default: NOTREACHED() << "Don't know how to print this value"; diff --git a/base/json/json_value_serializer_unittest.cc b/base/json/json_value_serializer_unittest.cc index 44c0a57..314cd07 100644 --- a/base/json/json_value_serializer_unittest.cc +++ b/base/json/json_value_serializer_unittest.cc @@ -235,23 +235,22 @@ TEST(JSONValueSerializerTest, StringEscape) { std::string all_chars_expected = "\\u0001\\u0002\\u0003\\u0004\\u0005\\u0006\\u0007\\b\\t\\n\\u000B\\f\\r" "\\u000E\\u000F\\u0010\\u0011\\u0012\\u0013\\u0014\\u0015\\u0016\\u0017" - "\\u0018\\u0019\\u001A\\u001B\\u001C\\u001D\\u001E\\u001F !\\\"#$%&'()*+," - "-./0123456789:;\\u003C=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\\\]^_`abcde" - "fghijklmnopqrstuvwxyz{|}~\x7F\xC2\x80\xC2\x81\xC2\x82\xC2\x83\xC2\x84" - "\xC2\x85\xC2\x86\xC2\x87\xC2\x88\xC2\x89\xC2\x8A\xC2\x8B\xC2\x8C\xC2\x8D" - "\xC2\x8E\xC2\x8F\xC2\x90\xC2\x91\xC2\x92\xC2\x93\xC2\x94\xC2\x95\xC2\x96" - "\xC2\x97\xC2\x98\xC2\x99\xC2\x9A\xC2\x9B\xC2\x9C\xC2\x9D\xC2\x9E\xC2\x9F" - "\xC2\xA0\xC2\xA1\xC2\xA2\xC2\xA3\xC2\xA4\xC2\xA5\xC2\xA6\xC2\xA7\xC2\xA8" - "\xC2\xA9\xC2\xAA\xC2\xAB\xC2\xAC\xC2\xAD\xC2\xAE\xC2\xAF\xC2\xB0\xC2\xB1" - "\xC2\xB2\xC2\xB3\xC2\xB4\xC2\xB5\xC2\xB6\xC2\xB7\xC2\xB8\xC2\xB9\xC2\xBA" - "\xC2\xBB\xC2\xBC\xC2\xBD\xC2\xBE\xC2\xBF\xC3\x80\xC3\x81\xC3\x82\xC3\x83" - "\xC3\x84\xC3\x85\xC3\x86\xC3\x87\xC3\x88\xC3\x89\xC3\x8A\xC3\x8B\xC3\x8C" - "\xC3\x8D\xC3\x8E\xC3\x8F\xC3\x90\xC3\x91\xC3\x92\xC3\x93\xC3\x94\xC3\x95" - "\xC3\x96\xC3\x97\xC3\x98\xC3\x99\xC3\x9A\xC3\x9B\xC3\x9C\xC3\x9D\xC3\x9E" - "\xC3\x9F\xC3\xA0\xC3\xA1\xC3\xA2\xC3\xA3\xC3\xA4\xC3\xA5\xC3\xA6\xC3\xA7" - "\xC3\xA8\xC3\xA9\xC3\xAA\xC3\xAB\xC3\xAC\xC3\xAD\xC3\xAE\xC3\xAF\xC3\xB0" - "\xC3\xB1\xC3\xB2\xC3\xB3\xC3\xB4\xC3\xB5\xC3\xB6\xC3\xB7\xC3\xB8\xC3\xB9" - "\xC3\xBA\xC3\xBB\xC3\xBC\xC3\xBD\xC3\xBE\xC3\xBF"; + "\\u0018\\u0019\\u001A\\u001B\\u001C\\u001D\\u001E\\u001F !\\\"" + "#$%&'()*+,-./0123456789:;\\u003C=\\u003E?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\" + "\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\\u007F\\u0080\\u0081\\u0082\\u0083" + "\\u0084\\u0085\\u0086\\u0087\\u0088\\u0089\\u008A\\u008B\\u008C\\u008D" + "\\u008E\\u008F\\u0090\\u0091\\u0092\\u0093\\u0094\\u0095\\u0096\\u0097" + "\\u0098\\u0099\\u009A\\u009B\\u009C\\u009D\\u009E\\u009F\\u00A0\\u00A1" + "\\u00A2\\u00A3\\u00A4\\u00A5\\u00A6\\u00A7\\u00A8\\u00A9\\u00AA\\u00AB" + "\\u00AC\\u00AD\\u00AE\\u00AF\\u00B0\\u00B1\\u00B2\\u00B3\\u00B4\\u00B5" + "\\u00B6\\u00B7\\u00B8\\u00B9\\u00BA\\u00BB\\u00BC\\u00BD\\u00BE\\u00BF" + "\\u00C0\\u00C1\\u00C2\\u00C3\\u00C4\\u00C5\\u00C6\\u00C7\\u00C8\\u00C9" + "\\u00CA\\u00CB\\u00CC\\u00CD\\u00CE\\u00CF\\u00D0\\u00D1\\u00D2\\u00D3" + "\\u00D4\\u00D5\\u00D6\\u00D7\\u00D8\\u00D9\\u00DA\\u00DB\\u00DC\\u00DD" + "\\u00DE\\u00DF\\u00E0\\u00E1\\u00E2\\u00E3\\u00E4\\u00E5\\u00E6\\u00E7" + "\\u00E8\\u00E9\\u00EA\\u00EB\\u00EC\\u00ED\\u00EE\\u00EF\\u00F0\\u00F1" + "\\u00F2\\u00F3\\u00F4\\u00F5\\u00F6\\u00F7\\u00F8\\u00F9\\u00FA\\u00FB" + "\\u00FC\\u00FD\\u00FE\\u00FF"; std::string expected_output = "{\"all_chars\":\"" + all_chars_expected + "\"}"; @@ -274,7 +273,7 @@ TEST(JSONValueSerializerTest, UnicodeStrings) { string16 test(WideToUTF16(L"\x7F51\x9875")); root.SetString("web", test); - std::string expected = "{\"web\":\"\xE7\xBD\x91\xE9\xA1\xB5\"}"; + std::string expected = "{\"web\":\"\\u7F51\\u9875\"}"; std::string actual; JSONStringValueSerializer serializer(&actual); diff --git a/base/json/json_writer.cc b/base/json/json_writer.cc index d600663..6a9cc6a 100644 --- a/base/json/json_writer.cc +++ b/base/json/json_writer.cc @@ -21,24 +21,28 @@ static const char kPrettyPrintLineEnding[] = "\r\n"; static const char kPrettyPrintLineEnding[] = "\n"; #endif -// static +/* static */ +const char* JSONWriter::kEmptyArray = "[]"; + +/* static */ void JSONWriter::Write(const Value* const node, std::string* json) { WriteWithOptions(node, 0, json); } -// static +/* static */ void JSONWriter::WriteWithOptions(const Value* const node, int options, std::string* json) { json->clear(); // Is there a better way to estimate the size of the output? json->reserve(1024); + bool escape = !(options & OPTIONS_DO_NOT_ESCAPE); bool omit_binary_values = !!(options & OPTIONS_OMIT_BINARY_VALUES); bool omit_double_type_preservation = !!(options & OPTIONS_OMIT_DOUBLE_TYPE_PRESERVATION); bool pretty_print = !!(options & OPTIONS_PRETTY_PRINT); - JSONWriter writer(omit_binary_values, omit_double_type_preservation, + JSONWriter writer(escape, omit_binary_values, omit_double_type_preservation, pretty_print, json); writer.BuildJSONString(node, 0); @@ -46,10 +50,11 @@ void JSONWriter::WriteWithOptions(const Value* const node, int options, json->append(kPrettyPrintLineEnding); } -JSONWriter::JSONWriter(bool omit_binary_values, +JSONWriter::JSONWriter(bool escape, bool omit_binary_values, bool omit_double_type_preservation, bool pretty_print, std::string* json) - : omit_binary_values_(omit_binary_values), + : escape_(escape), + omit_binary_values_(omit_binary_values), omit_double_type_preservation_(omit_double_type_preservation), pretty_print_(pretty_print), json_string_(json) { @@ -118,7 +123,11 @@ void JSONWriter::BuildJSONString(const Value* const node, int depth) { std::string value; bool result = node->GetAsString(&value); DCHECK(result); - EscapeJSONString(value, true, json_string_); + if (escape_) { + JsonDoubleQuote(UTF8ToUTF16(value), true, json_string_); + } else { + JsonDoubleQuote(value, true, json_string_); + } break; } @@ -160,7 +169,7 @@ void JSONWriter::BuildJSONString(const Value* const node, int depth) { json_string_->append(kPrettyPrintLineEnding); const DictionaryValue* dict = - static_cast<const DictionaryValue*>(node); + static_cast<const DictionaryValue*>(node); bool first_entry = true; for (DictionaryValue::Iterator itr(*dict); !itr.IsAtEnd(); itr.Advance(), first_entry = false) { @@ -177,8 +186,7 @@ void JSONWriter::BuildJSONString(const Value* const node, int depth) { if (pretty_print_) IndentLine(depth + 1); - - EscapeJSONString(itr.key(), true, json_string_); + AppendQuotedString(itr.key()); if (pretty_print_) { json_string_->append(": "); } else { @@ -210,6 +218,12 @@ void JSONWriter::BuildJSONString(const Value* const node, int depth) { } } +void JSONWriter::AppendQuotedString(const std::string& str) { + // TODO(viettrungluu): |str| is UTF-8, not ASCII, so to properly escape it we + // have to convert it to UTF-16. This round-trip is suboptimal. + JsonDoubleQuote(UTF8ToUTF16(str), true, json_string_); +} + void JSONWriter::IndentLine(int depth) { // It may be faster to keep an indent string so we don't have to keep // reallocating. diff --git a/base/json/json_writer.h b/base/json/json_writer.h index e4a143c..94052c8 100644 --- a/base/json/json_writer.h +++ b/base/json/json_writer.h @@ -17,19 +17,24 @@ class Value; class BASE_EXPORT JSONWriter { public: enum Options { + // Do not escape the string, preserving its UTF8 characters. It is useful + // if you can pass the resulting string to the JSON parser in binary form + // (as UTF8). + OPTIONS_DO_NOT_ESCAPE = 1 << 0, + // For values of binary type, the value (and key if within a dictionary) // will be omitted from the output. - OPTIONS_OMIT_BINARY_VALUES = 1 << 0, + OPTIONS_OMIT_BINARY_VALUES = 1 << 1, // This option instructs the writer to write doubles that have no fractional // part as a normal integer (i.e., without using exponential notation // or appending a '.0') as long as the value is within the range of a // 64-bit int. - OPTIONS_OMIT_DOUBLE_TYPE_PRESERVATION = 1 << 1, + OPTIONS_OMIT_DOUBLE_TYPE_PRESERVATION = 1 << 2, // Return a slightly nicer formatted json string (pads with whitespace to // help with readability). - OPTIONS_PRETTY_PRINT = 1 << 2, + OPTIONS_PRETTY_PRINT = 1 << 3 }; // Given a root node, generates a JSON string and puts it into |json|. @@ -43,8 +48,12 @@ class BASE_EXPORT JSONWriter { static void WriteWithOptions(const Value* const node, int options, std::string* json); + // A static, constant JSON string representing an empty array. Useful + // for empty JSON argument passing. + static const char* kEmptyArray; + private: - JSONWriter(bool omit_binary_values, + JSONWriter(bool escape, bool omit_binary_values, bool omit_double_type_preservation, bool pretty_print, std::string* json); @@ -52,9 +61,13 @@ class BASE_EXPORT JSONWriter { // json_string_ will contain the JSON. void BuildJSONString(const Value* const node, int depth); + // Appends a quoted, escaped, version of (UTF-8) str to json_string_. + void AppendQuotedString(const std::string& str); + // Adds space to json_string_ for the indent level. void IndentLine(int depth); + bool escape_; bool omit_binary_values_; bool omit_double_type_preservation_; bool pretty_print_; diff --git a/base/json/string_escape.cc b/base/json/string_escape.cc index a3b0735..10ea670 100644 --- a/base/json/string_escape.cc +++ b/base/json/string_escape.cc @@ -8,56 +8,40 @@ #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" -#include "base/strings/utf_string_conversion_utils.h" -#include "base/strings/utf_string_conversions.h" -#include "base/third_party/icu/icu_utf.h" namespace base { namespace { -// Format string for printing a \uXXXX escape sequence. -const char kU16EscapeFormat[] = "\\u%04X"; - -// The code point to output for an invalid input code unit. -const uint32 kReplacementCodePoint = 0xFFFD; - -// Used below in EscapeSpecialCodePoint(). -COMPILE_ASSERT('<' == 0x3C, less_than_sign_is_0x3c); - -// Try to escape the |code_point| if it is a known special character. If -// successful, returns true and appends the escape sequence to |dest|. This -// isn't required by the spec, but it's more readable by humans. -bool EscapeSpecialCodePoint(uint32 code_point, std::string* dest) { +// Try to escape |c| as a "SingleEscapeCharacter" (\n, etc). If successful, +// returns true and appends the escape sequence to |dst|. This isn't required +// by the spec, but it's more readable by humans than the \uXXXX alternatives. +template<typename CHAR> +static bool JsonSingleEscapeChar(const CHAR c, std::string* dst) { // WARNING: if you add a new case here, you need to update the reader as well. // Note: \v is in the reader, but not here since the JSON spec doesn't // allow it. - switch (code_point) { + switch (c) { case '\b': - dest->append("\\b"); + dst->append("\\b"); break; case '\f': - dest->append("\\f"); + dst->append("\\f"); break; case '\n': - dest->append("\\n"); + dst->append("\\n"); break; case '\r': - dest->append("\\r"); + dst->append("\\r"); break; case '\t': - dest->append("\\t"); + dst->append("\\t"); break; case '\\': - dest->append("\\\\"); + dst->append("\\\\"); break; case '"': - dest->append("\\\""); - break; - // Escape < to prevent script execution; escaping > is not necessary and - // not doing so save a few bytes. - case '<': - dest->append("\\u003C"); + dst->append("\\\""); break; default: return false; @@ -65,90 +49,57 @@ bool EscapeSpecialCodePoint(uint32 code_point, std::string* dest) { return true; } -template <typename S> -bool EscapeJSONStringImpl(const S& str, bool put_in_quotes, std::string* dest) { - bool did_replacement = false; - +template <class STR> +void JsonDoubleQuoteT(const STR& str, + bool put_in_quotes, + std::string* dst) { if (put_in_quotes) - dest->push_back('"'); - - // Casting is necessary because ICU uses int32. Try and do so safely. - CHECK_LE(str.length(), static_cast<size_t>(kint32max)); - const int32 length = static_cast<int32>(str.length()); - - for (int32 i = 0; i < length; ++i) { - uint32 code_point; - if (!ReadUnicodeCharacter(str.data(), length, &i, &code_point)) { - code_point = kReplacementCodePoint; - did_replacement = true; + dst->push_back('"'); + + for (typename STR::const_iterator it = str.begin(); it != str.end(); ++it) { + typename ToUnsigned<typename STR::value_type>::Unsigned c = *it; + if (!JsonSingleEscapeChar(c, dst)) { + if (c < 32 || c > 126 || c == '<' || c == '>') { + // 1. Escaping <, > to prevent script execution. + // 2. Technically, we could also pass through c > 126 as UTF8, but this + // is also optional. It would also be a pain to implement here. + unsigned int as_uint = static_cast<unsigned int>(c); + base::StringAppendF(dst, "\\u%04X", as_uint); + } else { + unsigned char ascii = static_cast<unsigned char>(*it); + dst->push_back(ascii); + } } - - if (EscapeSpecialCodePoint(code_point, dest)) - continue; - - // Escape non-printing characters. - if (code_point < 32) - base::StringAppendF(dest, kU16EscapeFormat, code_point); - else - WriteUnicodeCharacter(code_point, dest); } if (put_in_quotes) - dest->push_back('"'); - - return !did_replacement; + dst->push_back('"'); } } // namespace -bool EscapeJSONString(const StringPiece& str, - bool put_in_quotes, - std::string* dest) { - return EscapeJSONStringImpl(str, put_in_quotes, dest); +void JsonDoubleQuote(const StringPiece& str, + bool put_in_quotes, + std::string* dst) { + JsonDoubleQuoteT(str, put_in_quotes, dst); } -bool EscapeJSONString(const StringPiece16& str, - bool put_in_quotes, - std::string* dest) { - return EscapeJSONStringImpl(str, put_in_quotes, dest); -} - -std::string GetQuotedJSONString(const StringPiece& str) { - std::string dest; - bool ok = EscapeJSONStringImpl(str, true, &dest); - DCHECK(ok); - return dest; +std::string GetDoubleQuotedJson(const StringPiece& str) { + std::string dst; + JsonDoubleQuote(str, true, &dst); + return dst; } -std::string GetQuotedJSONString(const StringPiece16& str) { - std::string dest; - bool ok = EscapeJSONStringImpl(str, true, &dest); - DCHECK(ok); - return dest; +void JsonDoubleQuote(const StringPiece16& str, + bool put_in_quotes, + std::string* dst) { + JsonDoubleQuoteT(str, put_in_quotes, dst); } -std::string EscapeBytesAsInvalidJSONString(const StringPiece& str, - bool put_in_quotes) { - std::string dest; - - if (put_in_quotes) - dest.push_back('"'); - - for (StringPiece::const_iterator it = str.begin(); it != str.end(); ++it) { - ToUnsigned<StringPiece::value_type>::Unsigned c = *it; - if (EscapeSpecialCodePoint(c, &dest)) - continue; - - if (c < 32 || c > 126) - base::StringAppendF(&dest, kU16EscapeFormat, c); - else - dest.push_back(*it); - } - - if (put_in_quotes) - dest.push_back('"'); - - return dest; +std::string GetDoubleQuotedJson(const StringPiece16& str) { + std::string dst; + JsonDoubleQuote(str, true, &dst); + return dst; } } // namespace base diff --git a/base/json/string_escape.h b/base/json/string_escape.h index b66b7e5..0f16f59 100644 --- a/base/json/string_escape.h +++ b/base/json/string_escape.h @@ -1,8 +1,8 @@ // Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. - -// This file defines utility functions for escaping strings suitable for JSON. +// +// This file defines utility functions for escaping strings. #ifndef BASE_JSON_STRING_ESCAPE_H_ #define BASE_JSON_STRING_ESCAPE_H_ @@ -14,46 +14,24 @@ namespace base { -// Appends to |dest| an escaped version of |str|. Valid UTF-8 code units will -// pass through from the input to the output. Invalid code units will be -// replaced with the U+FFFD replacement character. This function returns true -// if no replacement was necessary and false if there was a lossy replacement. -// On return, |dest| will contain a valid UTF-8 JSON string. -// -// Non-printing control characters will be escaped as \uXXXX sequences for -// readability. -// -// If |put_in_quotes| is true, then a leading and trailing double-quote mark -// will be appended to |dest| as well. -BASE_EXPORT bool EscapeJSONString(const StringPiece& str, - bool put_in_quotes, - std::string* dest); - -// Performs a similar function to the UTF-8 StringPiece version above, -// converting UTF-16 code units to UTF-8 code units and escaping non-printing -// control characters. On return, |dest| will contain a valid UTF-8 JSON string. -BASE_EXPORT bool EscapeJSONString(const StringPiece16& str, - bool put_in_quotes, - std::string* dest); - -// Helper functions that wrap the above two functions but return the value -// instead of appending. |put_in_quotes| is always true. -BASE_EXPORT std::string GetQuotedJSONString(const StringPiece& str); -BASE_EXPORT std::string GetQuotedJSONString(const StringPiece16& str); - -// Given an arbitrary byte string |str|, this will escape all non-ASCII bytes -// as \uXXXX escape sequences. This function is *NOT* meant to be used with -// Unicode strings and does not validate |str| as one. -// -// CAVEAT CALLER: The output of this function may not be valid JSON, since -// JSON requires escape sequences to be valid UTF-16 code units. This output -// will be mangled if passed to to the base::JSONReader, since the reader will -// interpret it as UTF-16 and convert it to UTF-8. -// -// The output of this function takes the *appearance* of JSON but is not in -// fact valid according to RFC 4627. -BASE_EXPORT std::string EscapeBytesAsInvalidJSONString(const StringPiece& str, - bool put_in_quotes); +// Escape |str| appropriately for a JSON string literal, _appending_ the +// result to |dst|. This will create unicode escape sequences (\uXXXX). +// If |put_in_quotes| is true, the result will be surrounded in double quotes. +// The outputted literal, when interpreted by the browser, should result in a +// javascript string that is identical and the same length as the input |str|. +BASE_EXPORT void JsonDoubleQuote(const StringPiece& str, + bool put_in_quotes, + std::string* dst); + +// Same as above, but always returns the result double quoted. +BASE_EXPORT std::string GetDoubleQuotedJson(const StringPiece& str); + +BASE_EXPORT void JsonDoubleQuote(const StringPiece16& str, + bool put_in_quotes, + std::string* dst); + +// Same as above, but always returns the result double quoted. +BASE_EXPORT std::string GetDoubleQuotedJson(const StringPiece16& str); } // namespace base diff --git a/base/json/string_escape_unittest.cc b/base/json/string_escape_unittest.cc index 7d82f9b..f921994 100644 --- a/base/json/string_escape_unittest.cc +++ b/base/json/string_escape_unittest.cc @@ -1,182 +1,104 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "base/json/string_escape.h" - -#include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "testing/gtest/include/gtest/gtest.h" namespace base { -TEST(JSONStringEscapeTest, EscapeUTF8) { - const struct { - const char* to_escape; - const char* escaped; - } cases[] = { - {"\b\001aZ\"\\wee", "\\b\\u0001aZ\\\"\\\\wee"}, - {"a\b\f\n\r\t\v\1\\.\"z", - "a\\b\\f\\n\\r\\t\\u000B\\u0001\\\\.\\\"z"}, - {"b\x0f\x7f\xf0\xff!", // \xf0\xff is not a valid UTF-8 unit. - "b\\u000F\x7F\xEF\xBF\xBD\xEF\xBF\xBD!"}, - {"c<>d", "c\\u003C>d"}, - }; - - for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) { - const char* in_ptr = cases[i].to_escape; - std::string in_str = in_ptr; +namespace { - std::string out; - EscapeJSONString(in_ptr, false, &out); - EXPECT_EQ(std::string(cases[i].escaped), out); - EXPECT_TRUE(IsStringUTF8(out)); +const struct json_narrow_test_data { + const char* to_escape; + const char* escaped; +} json_narrow_cases[] = { + {"\b\001aZ\"\\wee", "\\b\\u0001aZ\\\"\\\\wee"}, + {"a\b\f\n\r\t\v\1\\.\"z", + "a\\b\\f\\n\\r\\t\\u000B\\u0001\\\\.\\\"z"}, + {"b\x0f\x7f\xf0\xff!", "b\\u000F\\u007F\\u00F0\\u00FF!"}, + {"c<>d", "c\\u003C\\u003Ed"}, +}; +} // namespace + +TEST(StringEscapeTest, JsonDoubleQuoteNarrow) { + for (size_t i = 0; i < arraysize(json_narrow_cases); ++i) { + const char* in_ptr = json_narrow_cases[i].to_escape; + std::string in_str = in_ptr; + std::string out; + JsonDoubleQuote(in_ptr, false, &out); + EXPECT_EQ(std::string(json_narrow_cases[i].escaped), out); out.erase(); - bool convert_ok = EscapeJSONString(in_str, false, &out); - EXPECT_EQ(std::string(cases[i].escaped), out); - EXPECT_TRUE(IsStringUTF8(out)); - - if (convert_ok) { - std::string fooout = GetQuotedJSONString(in_str); - EXPECT_EQ("\"" + std::string(cases[i].escaped) + "\"", fooout); - EXPECT_TRUE(IsStringUTF8(out)); - } + JsonDoubleQuote(in_str, false, &out); + EXPECT_EQ(std::string(json_narrow_cases[i].escaped), out); } - std::string in = cases[0].to_escape; + std::string in = json_narrow_cases[0].to_escape; std::string out; - EscapeJSONString(in, false, &out); - EXPECT_TRUE(IsStringUTF8(out)); + JsonDoubleQuote(in, false, &out); // test quoting std::string out_quoted; - EscapeJSONString(in, true, &out_quoted); + JsonDoubleQuote(in, true, &out_quoted); EXPECT_EQ(out.length() + 2, out_quoted.length()); EXPECT_EQ(out_quoted.find(out), 1U); - EXPECT_TRUE(IsStringUTF8(out_quoted)); // now try with a NULL in the string std::string null_prepend = "test"; null_prepend.push_back(0); in = null_prepend + in; std::string expected = "test\\u0000"; - expected += cases[0].escaped; + expected += json_narrow_cases[0].escaped; out.clear(); - EscapeJSONString(in, false, &out); + JsonDoubleQuote(in, false, &out); EXPECT_EQ(expected, out); - EXPECT_TRUE(IsStringUTF8(out)); } -TEST(JSONStringEscapeTest, EscapeUTF16) { - const struct { - const wchar_t* to_escape; - const char* escaped; - } cases[] = { - {L"b\uffb1\u00ff", "b\xEF\xBE\xB1\xC3\xBF"}, - {L"\b\001aZ\"\\wee", "\\b\\u0001aZ\\\"\\\\wee"}, - {L"a\b\f\n\r\t\v\1\\.\"z", - "a\\b\\f\\n\\r\\t\\u000B\\u0001\\\\.\\\"z"}, - {L"b\x0f\x7f\xf0\xff!", "b\\u000F\x7F\xC3\xB0\xC3\xBF!"}, - {L"c<>d", "c\\u003C>d"}, - }; - - for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) { - string16 in = WideToUTF16(cases[i].to_escape); +namespace { - std::string out; - EscapeJSONString(in, false, &out); - EXPECT_EQ(std::string(cases[i].escaped), out); - EXPECT_TRUE(IsStringUTF8(out)); +const struct json_wide_test_data { + const wchar_t* to_escape; + const char* escaped; +} json_wide_cases[] = { + {L"b\uffb1\u00ff", "b\\uFFB1\\u00FF"}, + {L"\b\001aZ\"\\wee", "\\b\\u0001aZ\\\"\\\\wee"}, + {L"a\b\f\n\r\t\v\1\\.\"z", + "a\\b\\f\\n\\r\\t\\u000B\\u0001\\\\.\\\"z"}, + {L"b\x0f\x7f\xf0\xff!", "b\\u000F\\u007F\\u00F0\\u00FF!"}, + {L"c<>d", "c\\u003C\\u003Ed"}, +}; - out = GetQuotedJSONString(in); - EXPECT_EQ("\"" + std::string(cases[i].escaped) + "\"", out); - EXPECT_TRUE(IsStringUTF8(out)); +} // namespace + +TEST(StringEscapeTest, JsonDoubleQuoteWide) { + for (size_t i = 0; i < arraysize(json_wide_cases); ++i) { + std::string out; + string16 in = WideToUTF16(json_wide_cases[i].to_escape); + JsonDoubleQuote(in, false, &out); + EXPECT_EQ(std::string(json_wide_cases[i].escaped), out); } - string16 in = WideToUTF16(cases[0].to_escape); + string16 in = WideToUTF16(json_wide_cases[0].to_escape); std::string out; - EscapeJSONString(in, false, &out); - EXPECT_TRUE(IsStringUTF8(out)); + JsonDoubleQuote(in, false, &out); // test quoting std::string out_quoted; - EscapeJSONString(in, true, &out_quoted); + JsonDoubleQuote(in, true, &out_quoted); EXPECT_EQ(out.length() + 2, out_quoted.length()); EXPECT_EQ(out_quoted.find(out), 1U); - EXPECT_TRUE(IsStringUTF8(out)); // now try with a NULL in the string string16 null_prepend = WideToUTF16(L"test"); null_prepend.push_back(0); in = null_prepend + in; std::string expected = "test\\u0000"; - expected += cases[0].escaped; + expected += json_wide_cases[0].escaped; out.clear(); - EscapeJSONString(in, false, &out); + JsonDoubleQuote(in, false, &out); EXPECT_EQ(expected, out); - EXPECT_TRUE(IsStringUTF8(out)); -} - -TEST(JSONStringEscapeTest, EscapeUTF16OutsideBMP) { - { - // {a, U+10300, !}, SMP. - string16 test; - test.push_back('a'); - test.push_back(0xD800); - test.push_back(0xDF00); - test.push_back('!'); - std::string actual; - EXPECT_TRUE(EscapeJSONString(test, false, &actual)); - EXPECT_EQ("a\xF0\x90\x8C\x80!", actual); - } - { - // {U+20021, U+2002B}, SIP. - string16 test; - test.push_back(0xD840); - test.push_back(0xDC21); - test.push_back(0xD840); - test.push_back(0xDC2B); - std::string actual; - EXPECT_TRUE(EscapeJSONString(test, false, &actual)); - EXPECT_EQ("\xF0\xA0\x80\xA1\xF0\xA0\x80\xAB", actual); - } - { - // {?, U+D800, @}, lone surrogate. - string16 test; - test.push_back('?'); - test.push_back(0xD800); - test.push_back('@'); - std::string actual; - EXPECT_FALSE(EscapeJSONString(test, false, &actual)); - EXPECT_EQ("?\xEF\xBF\xBD@", actual); - } -} - -TEST(JSONStringEscapeTest, EscapeBytes) { - const struct { - const char* to_escape; - const char* escaped; - } cases[] = { - {"b\x0f\x7f\xf0\xff!", "b\\u000F\\u007F\\u00F0\\u00FF!"}, - {"\xe5\xc4\x4f\x05\xb6\xfd\0", "\\u00E5\\u00C4O\\u0005\\u00B6\\u00FD"}, - }; - - for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) { - std::string in = std::string(cases[i].to_escape); - EXPECT_FALSE(IsStringUTF8(in)); - - EXPECT_EQ(std::string(cases[i].escaped), - EscapeBytesAsInvalidJSONString(in, false)); - EXPECT_EQ("\"" + std::string(cases[i].escaped) + "\"", - EscapeBytesAsInvalidJSONString(in, true)); - } - - const char kEmbedNull[] = { '\xab', '\x39', '\0', '\x9f', '\xab' }; - std::string in(kEmbedNull, ARRAYSIZE_UNSAFE(kEmbedNull)); - EXPECT_FALSE(IsStringUTF8(in)); - EXPECT_EQ(std::string("\\u00AB9\\u0000\\u009F\\u00AB"), - EscapeBytesAsInvalidJSONString(in, false)); } } // namespace base diff --git a/base/metrics/statistics_recorder.cc b/base/metrics/statistics_recorder.cc index 62617c5..2753c0b2 100644 --- a/base/metrics/statistics_recorder.cc +++ b/base/metrics/statistics_recorder.cc @@ -172,7 +172,7 @@ std::string StatisticsRecorder::ToJSON(const std::string& query) { std::string output("{"); if (!query.empty()) { output += "\"query\":"; - EscapeJSONString(query, true, &output); + JsonDoubleQuote(query, true, &output); output += ","; } diff --git a/chrome/browser/chromeos/policy/configuration_policy_handler_chromeos.cc b/chrome/browser/chromeos/policy/configuration_policy_handler_chromeos.cc index 1df3387..611ea7a 100644 --- a/chrome/browser/chromeos/policy/configuration_policy_handler_chromeos.cc +++ b/chrome/browser/chromeos/policy/configuration_policy_handler_chromeos.cc @@ -246,7 +246,8 @@ base::Value* NetworkConfigurationPolicyHandler::SanitizeNetworkConfig( kPlaceholder); base::JSONWriter::WriteWithOptions(toplevel_dict.get(), - base::JSONWriter::OPTIONS_PRETTY_PRINT, + base::JSONWriter::OPTIONS_DO_NOT_ESCAPE | + base::JSONWriter::OPTIONS_PRETTY_PRINT, &json_string); return base::Value::CreateStringValue(json_string); } diff --git a/chrome/browser/extensions/activity_log/activity_log_unittest.cc b/chrome/browser/extensions/activity_log/activity_log_unittest.cc index fedd5fe..2d11ca5 100644 --- a/chrome/browser/extensions/activity_log/activity_log_unittest.cc +++ b/chrome/browser/extensions/activity_log/activity_log_unittest.cc @@ -117,7 +117,7 @@ class ActivityLogTest : public ChromeRenderViewHostTestHarness { ASSERT_EQ(4U, i->size()); scoped_refptr<Action> action = i->at(0); ASSERT_EQ("XMLHttpRequest.open", action->api_name()); - ASSERT_EQ("[\"POST\",\"\\u003Carg_url>\"]", + ASSERT_EQ("[\"POST\",\"\\u003Carg_url\\u003E\"]", ActivityLogPolicy::Util::Serialize(action->args())); ASSERT_EQ("http://api.google.com/", action->arg_url().spec()); // Test that the dom_verb field was changed to XHR (from METHOD). This @@ -131,7 +131,7 @@ class ActivityLogTest : public ChromeRenderViewHostTestHarness { action = i->at(1); ASSERT_EQ("XMLHttpRequest.open", action->api_name()); - ASSERT_EQ("[\"POST\",\"\\u003Carg_url>\"]", + ASSERT_EQ("[\"POST\",\"\\u003Carg_url\\u003E\"]", ActivityLogPolicy::Util::Serialize(action->args())); ASSERT_EQ("http://www.google.com/api/", action->arg_url().spec()); @@ -143,7 +143,7 @@ class ActivityLogTest : public ChromeRenderViewHostTestHarness { action = i->at(3); ASSERT_EQ("windows.create", action->api_name()); - ASSERT_EQ("[{\"url\":\"\\u003Carg_url>\"}]", + ASSERT_EQ("[{\"url\":\"\\u003Carg_url\\u003E\"}]", ActivityLogPolicy::Util::Serialize(action->args())); ASSERT_EQ("http://www.google.co.uk/", action->arg_url().spec()); } diff --git a/chrome/browser/extensions/api/messaging/native_messaging_host_manifest_unittest.cc b/chrome/browser/extensions/api/messaging/native_messaging_host_manifest_unittest.cc index 841ace2..58982a2 100644 --- a/chrome/browser/extensions/api/messaging/native_messaging_host_manifest_unittest.cc +++ b/chrome/browser/extensions/api/messaging/native_messaging_host_manifest_unittest.cc @@ -34,10 +34,12 @@ class NativeMessagingHostManifestTest : public ::testing::Test { bool WriteManifest(const std::string& name, const std::string& path, const std::string& origin) { + std::string escaped_path; + base::JsonDoubleQuote(path, false, &escaped_path); return WriteManifest("{" " \"name\": \"" + name + "\"," " \"description\": \"Native Messaging Test\"," - " \"path\": " + base::GetQuotedJSONString(path) + "," + " \"path\": \"" + escaped_path + "\"," " \"type\": \"stdio\"," " \"allowed_origins\": [" " \"" + origin + "\"" diff --git a/chrome/browser/search/iframe_source.cc b/chrome/browser/search/iframe_source.cc index 16d6c41..b44ed30 100644 --- a/chrome/browser/search/iframe_source.cc +++ b/chrome/browser/search/iframe_source.cc @@ -4,6 +4,7 @@ #include "chrome/browser/search/iframe_source.h" +#include "base/json/string_escape.h" #include "base/memory/ref_counted_memory.h" #include "base/strings/string_piece.h" #include "base/strings/string_util.h" @@ -86,6 +87,8 @@ void IframeSource::SendJSWithOrigin( return; } + std::string js_escaped_origin; + base::JsonDoubleQuote(origin, false, &js_escaped_origin); base::StringPiece template_js = ResourceBundle::GetSharedInstance().GetRawDataResource(resource_id); std::string response(template_js.as_string()); diff --git a/chrome/browser/spellchecker/spelling_service_client.cc b/chrome/browser/spellchecker/spelling_service_client.cc index ab15a3e..dbe92a3 100644 --- a/chrome/browser/spellchecker/spelling_service_client.cc +++ b/chrome/browser/spellchecker/spelling_service_client.cc @@ -69,20 +69,21 @@ bool SpellingServiceClient::RequestTextCheck( &country_code); // Format the JSON request to be sent to the Spelling service. - std::string encoded_text = base::GetQuotedJSONString(text); + std::string encoded_text; + base::JsonDoubleQuote(text, false, &encoded_text); static const char kSpellingRequest[] = "{" "\"method\":\"spelling.check\"," "\"apiVersion\":\"v%d\"," "\"params\":{" - "\"text\":%s," + "\"text\":\"%s\"," "\"language\":\"%s\"," "\"originCountry\":\"%s\"," "\"key\":%s" "}" "}"; - std::string api_key = base::GetQuotedJSONString(google_apis::GetAPIKey()); + std::string api_key = base::GetDoubleQuotedJson(google_apis::GetAPIKey()); std::string request = base::StringPrintf( kSpellingRequest, type, diff --git a/chrome/browser/ui/webui/about_ui.cc b/chrome/browser/ui/webui/about_ui.cc index 5e87c39..1733570 100644 --- a/chrome/browser/ui/webui/about_ui.cc +++ b/chrome/browser/ui/webui/about_ui.cc @@ -708,7 +708,8 @@ std::string AboutStats(const std::string& query) { if (query == "json" || query == kStringsJsPath) { base::JSONWriter::WriteWithOptions( &root, - base::JSONWriter::OPTIONS_PRETTY_PRINT, + base::JSONWriter::OPTIONS_DO_NOT_ESCAPE | + base::JSONWriter::OPTIONS_PRETTY_PRINT, &data); if (query == kStringsJsPath) data = "var templateData = " + data + ";"; diff --git a/chrome/browser/ui/webui/policy_ui.cc b/chrome/browser/ui/webui/policy_ui.cc index dc9bd55..b5020f5 100644 --- a/chrome/browser/ui/webui/policy_ui.cc +++ b/chrome/browser/ui/webui/policy_ui.cc @@ -178,7 +178,8 @@ scoped_ptr<base::StringValue> DictionaryToJSONString( const base::DictionaryValue* dict) { std::string json_string; base::JSONWriter::WriteWithOptions(dict, - base::JSONWriter::OPTIONS_PRETTY_PRINT, + base::JSONWriter::OPTIONS_DO_NOT_ESCAPE | + base::JSONWriter::OPTIONS_PRETTY_PRINT, &json_string); return make_scoped_ptr(new base::StringValue(json_string)); } diff --git a/chrome/renderer/searchbox/searchbox_extension.cc b/chrome/renderer/searchbox/searchbox_extension.cc index 19bc48b..f34b102 100644 --- a/chrome/renderer/searchbox/searchbox_extension.cc +++ b/chrome/renderer/searchbox/searchbox_extension.cc @@ -460,7 +460,8 @@ void SearchBoxExtension::DispatchChromeIdentityCheckResult( blink::WebFrame* frame, const base::string16& identity, bool identity_match) { - std::string escaped_identity = base::GetQuotedJSONString(identity); + std::string escaped_identity; + base::JsonDoubleQuote(identity, true, &escaped_identity); blink::WebString script(UTF8ToUTF16(base::StringPrintf( kDispatchChromeIdentityCheckResult, escaped_identity.c_str(), diff --git a/chrome/test/chromedriver/capabilities.cc b/chrome/test/chromedriver/capabilities.cc index 0d2fb8e..8479a84 100644 --- a/chrome/test/chromedriver/capabilities.cc +++ b/chrome/test/chromedriver/capabilities.cc @@ -395,7 +395,7 @@ std::string Switches::ToString() const { std::string value = GetSwitchValue(iter->first); if (value.length()) { if (value.find(' ') != std::string::npos) - value = base::GetQuotedJSONString(value); + value = base::GetDoubleQuotedJson(value); str += "=" + value; } ++iter; diff --git a/chrome/test/chromedriver/chrome/adb_impl.cc b/chrome/test/chromedriver/chrome/adb_impl.cc index 0fa1478..b2373e5 100644 --- a/chrome/test/chromedriver/chrome/adb_impl.cc +++ b/chrome/test/chromedriver/chrome/adb_impl.cc @@ -119,7 +119,7 @@ Status AdbImpl::SetCommandLineFile(const std::string& device_serial, const std::string& args) { std::string response; std::string quoted_command = - base::GetQuotedJSONString(exec_name + " " + args); + base::GetDoubleQuotedJson(exec_name + " " + args); Status status = ExecuteHostShellCommand( device_serial, base::StringPrintf("echo %s > %s; echo $?", diff --git a/components/plugins/renderer/plugin_placeholder.cc b/components/plugins/renderer/plugin_placeholder.cc index bb429cd..b8f050f 100644 --- a/components/plugins/renderer/plugin_placeholder.cc +++ b/components/plugins/renderer/plugin_placeholder.cc @@ -165,7 +165,7 @@ void PluginPlaceholder::SetMessage(const base::string16& message) { void PluginPlaceholder::UpdateMessage() { std::string script = - "window.setMessage(" + base::GetQuotedJSONString(message_) + ")"; + "window.setMessage(" + base::GetDoubleQuotedJson(message_) + ")"; plugin_->web_view()->mainFrame()->executeScript( WebScriptSource(ASCIIToUTF16(script))); } diff --git a/jingle/notifier/listener/notification_defines.cc b/jingle/notifier/listener/notification_defines.cc index f7c8f8f..f4f3e40 100644 --- a/jingle/notifier/listener/notification_defines.cc +++ b/jingle/notifier/listener/notification_defines.cc @@ -65,12 +65,10 @@ bool Notification::Equals(const Notification& other) const { } std::string Notification::ToString() const { - // |channel| or |data| could hold binary data, so convert all non-ASCII - // characters to escape sequences. - const std::string& printable_channel = - base::EscapeBytesAsInvalidJSONString(channel, true /* put_in_quotes */); - const std::string& printable_data = - base::EscapeBytesAsInvalidJSONString(data, true /* put_in_quotes */); + // |channel| or |data| could hold binary data, so use GetDoubleQuotedJson() + // to escape them. + const std::string& printable_channel = base::GetDoubleQuotedJson(channel); + const std::string& printable_data = base::GetDoubleQuotedJson(data); return "{ channel: " + printable_channel + ", data: " + printable_data + " }"; } diff --git a/net/base/net_util.cc b/net/base/net_util.cc index 1f69ee7..241d748 100644 --- a/net/base/net_util.cc +++ b/net/base/net_util.cc @@ -1095,7 +1095,7 @@ std::string GetDirectoryListingHeader(const base::string16& title) { result.assign(header.data(), header.size()); result.append("<script>start("); - base::EscapeJSONString(title, true, &result); + base::JsonDoubleQuote(title, true, &result); result.append(");</script>\n"); return result; @@ -1149,12 +1149,13 @@ std::string GetDirectoryListingEntry(const base::string16& name, Time modified) { std::string result; result.append("<script>addRow("); - base::EscapeJSONString(name, true, &result); + base::JsonDoubleQuote(name, true, &result); result.append(","); if (raw_bytes.empty()) { - base::EscapeJSONString(EscapePath(UTF16ToUTF8(name)), true, &result); + base::JsonDoubleQuote(EscapePath(UTF16ToUTF8(name)), + true, &result); } else { - base::EscapeJSONString(EscapePath(raw_bytes), true, &result); + base::JsonDoubleQuote(EscapePath(raw_bytes), true, &result); } if (is_dir) { result.append(",1,"); @@ -1166,7 +1167,7 @@ std::string GetDirectoryListingEntry(const base::string16& name, base::string16 size_string; if (size >= 0) size_string = FormatBytesUnlocalized(size); - base::EscapeJSONString(size_string, true, &result); + base::JsonDoubleQuote(size_string, true, &result); result.append(","); @@ -1175,7 +1176,7 @@ std::string GetDirectoryListingEntry(const base::string16& name, if (!modified.is_null()) { modified_str = base::TimeFormatShortDateAndTime(modified); } - base::EscapeJSONString(modified_str, true, &result); + base::JsonDoubleQuote(modified_str, true, &result); result.append(");</script>\n"); diff --git a/net/base/net_util_unittest.cc b/net/base/net_util_unittest.cc index 2259629..38cc408 100644 --- a/net/base/net_util_unittest.cc +++ b/net/base/net_util_unittest.cc @@ -2260,8 +2260,8 @@ TEST(NetUtilTest, GetDirectoryListingEntry) { false, 10000, base::Time(), - "<script>addRow(\"\xED\x95\x9C\xEA\xB8\x80.txt\"," - "\"%ED%95%9C%EA%B8%80.txt\",0,\"9.8 kB\",\"\");</script>\n"}, + "<script>addRow(\"\\uD55C\\uAE00.txt\",\"%ED%95%9C%EA%B8%80.txt\"" + ",0,\"9.8 kB\",\"\");</script>\n"}, // U+D55C0 U+AE00. raw_bytes is the corresponding EUC-KR sequence: // a local or remote file in EUC-KR. {L"\xD55C\xAE00.txt", @@ -2269,7 +2269,7 @@ TEST(NetUtilTest, GetDirectoryListingEntry) { false, 10000, base::Time(), - "<script>addRow(\"\xED\x95\x9C\xEA\xB8\x80.txt\",\"%C7%D1%B1%DB.txt\"" + "<script>addRow(\"\\uD55C\\uAE00.txt\",\"%C7%D1%B1%DB.txt\"" ",0,\"9.8 kB\",\"\");</script>\n"}, }; diff --git a/sync/internal_api/public/base/ordinal.h b/sync/internal_api/public/base/ordinal.h index cb67b45..c347b7b 100644 --- a/sync/internal_api/public/base/ordinal.h +++ b/sync/internal_api/public/base/ordinal.h @@ -260,8 +260,8 @@ bool Ordinal<Traits>::EqualsOrBothInvalid(const Ordinal& other) const { template <typename Traits> std::string Ordinal<Traits>::ToDebugString() const { - std::string debug_string = - base::EscapeBytesAsInvalidJSONString(bytes_, false /* put_in_quotes */); + std::string debug_string; + base::JsonDoubleQuote(bytes_, false /* put_in_quotes */, &debug_string); if (!is_valid_) { debug_string = "INVALID[" + debug_string + "]"; } diff --git a/sync/internal_api/public/base/progress_marker_map.cc b/sync/internal_api/public/base/progress_marker_map.cc index ea1f177..b281013 100644 --- a/sync/internal_api/public/base/progress_marker_map.cc +++ b/sync/internal_api/public/base/progress_marker_map.cc @@ -16,8 +16,9 @@ scoped_ptr<base::DictionaryValue> ProgressMarkerMapToValue( for (ProgressMarkerMap::const_iterator it = marker_map.begin(); it != marker_map.end(); ++it) { std::string printable_payload; - base::EscapeJSONString( - it->second, false /* put_in_quotes */, &printable_payload); + base::JsonDoubleQuote(it->second, + false /* put_in_quotes */, + &printable_payload); value->SetString(ModelTypeToString(it->first), printable_payload); } return value.Pass(); diff --git a/sync/syncable/entry.cc b/sync/syncable/entry.cc index 852c33e..3891c55 100644 --- a/sync/syncable/entry.cc +++ b/sync/syncable/entry.cc @@ -147,9 +147,11 @@ std::ostream& operator<<(std::ostream& os, const Entry& entry) { os << g_metas_columns[i].name << ": " << field << ", "; } for ( ; i < PROTO_FIELDS_END; ++i) { - std::string escaped_str = base::EscapeBytesAsInvalidJSONString( + std::string escaped_str; + base::JsonDoubleQuote( kernel->ref(static_cast<ProtoField>(i)).SerializeAsString(), - false); + false, + &escaped_str); os << g_metas_columns[i].name << ": " << escaped_str << ", "; } for ( ; i < UNIQUE_POSITION_FIELDS_END; ++i) { diff --git a/tools/gn/trace.cc b/tools/gn/trace.cc index 18082c4..aa73eba 100644 --- a/tools/gn/trace.cc +++ b/tools/gn/trace.cc @@ -241,7 +241,7 @@ void SaveTraces(const base::FilePath& file_name) { out << ",\"dur\":" << item.delta().InMicroseconds(); quote_buffer.resize(0); - base::EscapeJSONString(item.name(), true, "e_buffer); + base::JsonDoubleQuote(item.name(), true, "e_buffer); out << ",\"name\":" << quote_buffer; out << ",\"cat\":"; @@ -270,13 +270,13 @@ void SaveTraces(const base::FilePath& file_name) { bool needs_comma = false; if (!item.toolchain().empty()) { quote_buffer.resize(0); - base::EscapeJSONString(item.toolchain(), true, "e_buffer); + base::JsonDoubleQuote(item.toolchain(), true, "e_buffer); out << "\"toolchain\":" << quote_buffer; needs_comma = true; } if (!item.cmdline().empty()) { quote_buffer.resize(0); - base::EscapeJSONString(item.cmdline(), true, "e_buffer); + base::JsonDoubleQuote(item.cmdline(), true, "e_buffer); if (needs_comma) out << ","; out << "\"cmdline\":" << quote_buffer; |