OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/json/string_escape.h" | 5 #include "base/json/string_escape.h" |
6 | 6 |
| 7 #include <stdint.h> |
| 8 |
| 9 #include <limits> |
7 #include <string> | 10 #include <string> |
8 | 11 |
9 #include "base/strings/string_util.h" | 12 #include "base/strings/string_util.h" |
10 #include "base/strings/stringprintf.h" | 13 #include "base/strings/stringprintf.h" |
11 #include "base/strings/utf_string_conversion_utils.h" | 14 #include "base/strings/utf_string_conversion_utils.h" |
12 #include "base/strings/utf_string_conversions.h" | 15 #include "base/strings/utf_string_conversions.h" |
13 #include "base/third_party/icu/icu_utf.h" | 16 #include "base/third_party/icu/icu_utf.h" |
14 | 17 |
15 namespace base { | 18 namespace base { |
16 | 19 |
17 namespace { | 20 namespace { |
18 | 21 |
19 // Format string for printing a \uXXXX escape sequence. | 22 // Format string for printing a \uXXXX escape sequence. |
20 const char kU16EscapeFormat[] = "\\u%04X"; | 23 const char kU16EscapeFormat[] = "\\u%04X"; |
21 | 24 |
22 // The code point to output for an invalid input code unit. | 25 // The code point to output for an invalid input code unit. |
23 const uint32 kReplacementCodePoint = 0xFFFD; | 26 const uint32_t kReplacementCodePoint = 0xFFFD; |
24 | 27 |
25 // Used below in EscapeSpecialCodePoint(). | 28 // Used below in EscapeSpecialCodePoint(). |
26 static_assert('<' == 0x3C, "less than sign must be 0x3c"); | 29 static_assert('<' == 0x3C, "less than sign must be 0x3c"); |
27 | 30 |
28 // Try to escape the |code_point| if it is a known special character. If | 31 // Try to escape the |code_point| if it is a known special character. If |
29 // successful, returns true and appends the escape sequence to |dest|. This | 32 // successful, returns true and appends the escape sequence to |dest|. This |
30 // isn't required by the spec, but it's more readable by humans. | 33 // isn't required by the spec, but it's more readable by humans. |
31 bool EscapeSpecialCodePoint(uint32 code_point, std::string* dest) { | 34 bool EscapeSpecialCodePoint(uint32_t code_point, std::string* dest) { |
32 // WARNING: if you add a new case here, you need to update the reader as well. | 35 // WARNING: if you add a new case here, you need to update the reader as well. |
33 // Note: \v is in the reader, but not here since the JSON spec doesn't | 36 // Note: \v is in the reader, but not here since the JSON spec doesn't |
34 // allow it. | 37 // allow it. |
35 switch (code_point) { | 38 switch (code_point) { |
36 case '\b': | 39 case '\b': |
37 dest->append("\\b"); | 40 dest->append("\\b"); |
38 break; | 41 break; |
39 case '\f': | 42 case '\f': |
40 dest->append("\\f"); | 43 dest->append("\\f"); |
41 break; | 44 break; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
73 return true; | 76 return true; |
74 } | 77 } |
75 | 78 |
76 template <typename S> | 79 template <typename S> |
77 bool EscapeJSONStringImpl(const S& str, bool put_in_quotes, std::string* dest) { | 80 bool EscapeJSONStringImpl(const S& str, bool put_in_quotes, std::string* dest) { |
78 bool did_replacement = false; | 81 bool did_replacement = false; |
79 | 82 |
80 if (put_in_quotes) | 83 if (put_in_quotes) |
81 dest->push_back('"'); | 84 dest->push_back('"'); |
82 | 85 |
83 // Casting is necessary because ICU uses int32. Try and do so safely. | 86 // Casting is necessary because ICU uses int32_t. Try and do so safely. |
84 CHECK_LE(str.length(), static_cast<size_t>(kint32max)); | 87 CHECK_LE(str.length(), |
85 const int32 length = static_cast<int32>(str.length()); | 88 static_cast<size_t>(std::numeric_limits<int32_t>::max())); |
| 89 const int32_t length = static_cast<int32_t>(str.length()); |
86 | 90 |
87 for (int32 i = 0; i < length; ++i) { | 91 for (int32_t i = 0; i < length; ++i) { |
88 uint32 code_point; | 92 uint32_t code_point; |
89 if (!ReadUnicodeCharacter(str.data(), length, &i, &code_point)) { | 93 if (!ReadUnicodeCharacter(str.data(), length, &i, &code_point)) { |
90 code_point = kReplacementCodePoint; | 94 code_point = kReplacementCodePoint; |
91 did_replacement = true; | 95 did_replacement = true; |
92 } | 96 } |
93 | 97 |
94 if (EscapeSpecialCodePoint(code_point, dest)) | 98 if (EscapeSpecialCodePoint(code_point, dest)) |
95 continue; | 99 continue; |
96 | 100 |
97 // Escape non-printing characters. | 101 // Escape non-printing characters. |
98 if (code_point < 32) | 102 if (code_point < 32) |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
153 dest.push_back(*it); | 157 dest.push_back(*it); |
154 } | 158 } |
155 | 159 |
156 if (put_in_quotes) | 160 if (put_in_quotes) |
157 dest.push_back('"'); | 161 dest.push_back('"'); |
158 | 162 |
159 return dest; | 163 return dest; |
160 } | 164 } |
161 | 165 |
162 } // namespace base | 166 } // namespace base |
OLD | NEW |