This source file includes following definitions.
- EscapeSpecialCodePoint
- EscapeJSONStringImpl
- EscapeJSONString
- EscapeJSONString
- GetQuotedJSONString
- GetQuotedJSONString
- EscapeBytesAsInvalidJSONString
#include "base/json/string_escape.h"
#include <string>
#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 {
const char kU16EscapeFormat[] = "\\u%04X";
const uint32 kReplacementCodePoint = 0xFFFD;
COMPILE_ASSERT('<' == 0x3C, less_than_sign_is_0x3c);
bool EscapeSpecialCodePoint(uint32 code_point, std::string* dest) {
switch (code_point) {
case '\b':
dest->append("\\b");
break;
case '\f':
dest->append("\\f");
break;
case '\n':
dest->append("\\n");
break;
case '\r':
dest->append("\\r");
break;
case '\t':
dest->append("\\t");
break;
case '\\':
dest->append("\\\\");
break;
case '"':
dest->append("\\\"");
break;
case '<':
dest->append("\\u003C");
break;
default:
return false;
}
return true;
}
template <typename S>
bool EscapeJSONStringImpl(const S& str, bool put_in_quotes, std::string* dest) {
bool did_replacement = false;
if (put_in_quotes)
dest->push_back('"');
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;
}
if (EscapeSpecialCodePoint(code_point, dest))
continue;
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;
}
}
bool EscapeJSONString(const StringPiece& str,
bool put_in_quotes,
std::string* dest) {
return EscapeJSONStringImpl(str, put_in_quotes, dest);
}
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 GetQuotedJSONString(const StringPiece16& str) {
std::string dest;
bool ok = EscapeJSONStringImpl(str, true, &dest);
DCHECK(ok);
return dest;
}
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;
}
}