1// Copyright (c) 2006-2008 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 <string> 8 9#include "base/string_util.h" 10 11namespace base { 12 13namespace { 14 15// Try to escape |c| as a "SingleEscapeCharacter" (\n, etc). If successful, 16// returns true and appends the escape sequence to |dst|. This isn't required 17// by the spec, but it's more readable by humans than the \uXXXX alternatives. 18template<typename CHAR> 19static bool JsonSingleEscapeChar(const CHAR c, std::string* dst) { 20 // WARNING: if you add a new case here, you need to update the reader as well. 21 // Note: \v is in the reader, but not here since the JSON spec doesn't 22 // allow it. 23 switch (c) { 24 case '\b': 25 dst->append("\\b"); 26 break; 27 case '\f': 28 dst->append("\\f"); 29 break; 30 case '\n': 31 dst->append("\\n"); 32 break; 33 case '\r': 34 dst->append("\\r"); 35 break; 36 case '\t': 37 dst->append("\\t"); 38 break; 39 case '\\': 40 dst->append("\\\\"); 41 break; 42 case '"': 43 dst->append("\\\""); 44 break; 45 default: 46 return false; 47 } 48 return true; 49} 50 51template <class STR> 52void JsonDoubleQuoteT(const STR& str, 53 bool put_in_quotes, 54 std::string* dst) { 55 if (put_in_quotes) 56 dst->push_back('"'); 57 58 for (typename STR::const_iterator it = str.begin(); it != str.end(); ++it) { 59 typename ToUnsigned<typename STR::value_type>::Unsigned c = *it; 60 if (!JsonSingleEscapeChar(c, dst)) { 61 if (c < 32 || c > 126 || c == '<' || c == '>') { 62 // 1. Escaping <, > to prevent script execution. 63 // 2. Technically, we could also pass through c > 126 as UTF8, but this 64 // is also optional. It would also be a pain to implement here. 65 unsigned int as_uint = static_cast<unsigned int>(c); 66 StringAppendF(dst, "\\u%04X", as_uint); 67 } else { 68 unsigned char ascii = static_cast<unsigned char>(*it); 69 dst->push_back(ascii); 70 } 71 } 72 } 73 74 if (put_in_quotes) 75 dst->push_back('"'); 76} 77 78} // namespace 79 80void JsonDoubleQuote(const std::string& str, 81 bool put_in_quotes, 82 std::string* dst) { 83 JsonDoubleQuoteT(str, put_in_quotes, dst); 84} 85 86std::string GetDoubleQuotedJson(const std::string& str) { 87 std::string dst; 88 JsonDoubleQuote(str, true, &dst); 89 return dst; 90} 91 92void JsonDoubleQuote(const string16& str, 93 bool put_in_quotes, 94 std::string* dst) { 95 JsonDoubleQuoteT(str, put_in_quotes, dst); 96} 97 98std::string GetDoubleQuotedJson(const string16& str) { 99 std::string dst; 100 JsonDoubleQuote(str, true, &dst); 101 return dst; 102} 103 104} // namespace base 105