OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 "platform/inspector_protocol/Values.h" | 5 #include "platform/inspector_protocol/Values.h" |
6 | 6 |
7 #include "platform/Decimal.h" | |
8 #include "platform/inspector_protocol/Parser.h" | 7 #include "platform/inspector_protocol/Parser.h" |
9 #include "wtf/text/StringBuilder.h" | 8 #include "platform/inspector_protocol/String16.h" |
10 #include <cmath> | 9 #include <cmath> |
11 | 10 |
12 namespace blink { | 11 namespace blink { |
13 namespace protocol { | 12 namespace protocol { |
14 | 13 |
15 namespace { | 14 namespace { |
16 | 15 |
17 const char* const nullString = "null"; | 16 const char* const nullString = "null"; |
18 const char* const trueString = "true"; | 17 const char* const trueString = "true"; |
19 const char* const falseString = "false"; | 18 const char* const falseString = "false"; |
20 | 19 |
21 inline bool escapeChar(UChar c, StringBuilder* dst) | 20 inline bool escapeChar(UChar c, String16Builder* dst) |
22 { | 21 { |
23 switch (c) { | 22 switch (c) { |
24 case '\b': dst->appendLiteral("\\b"); break; | 23 case '\b': dst->append("\\b"); break; |
25 case '\f': dst->appendLiteral("\\f"); break; | 24 case '\f': dst->append("\\f"); break; |
26 case '\n': dst->appendLiteral("\\n"); break; | 25 case '\n': dst->append("\\n"); break; |
27 case '\r': dst->appendLiteral("\\r"); break; | 26 case '\r': dst->append("\\r"); break; |
28 case '\t': dst->appendLiteral("\\t"); break; | 27 case '\t': dst->append("\\t"); break; |
29 case '\\': dst->appendLiteral("\\\\"); break; | 28 case '\\': dst->append("\\\\"); break; |
30 case '"': dst->appendLiteral("\\\""); break; | 29 case '"': dst->append("\\\""); break; |
31 default: | 30 default: |
32 return false; | 31 return false; |
33 } | 32 } |
34 return true; | 33 return true; |
35 } | 34 } |
36 | 35 |
37 void escapeStringForJSON(const String& str, StringBuilder* dst) | 36 const LChar hexDigits[17] = "0123456789ABCDEF"; |
| 37 |
| 38 void appendUnsignedAsHex(UChar number, String16Builder* dst) |
| 39 { |
| 40 dst->append("\\u"); |
| 41 for (size_t i = 0; i < 4; ++i) { |
| 42 dst->append(hexDigits[(number & 0xF000) >> 12]); |
| 43 number <<= 4; |
| 44 } |
| 45 } |
| 46 |
| 47 void escapeStringForJSON(const String16& str, String16Builder* dst) |
38 { | 48 { |
39 for (unsigned i = 0; i < str.length(); ++i) { | 49 for (unsigned i = 0; i < str.length(); ++i) { |
40 UChar c = str[i]; | 50 UChar c = str[i]; |
41 if (!escapeChar(c, dst)) { | 51 if (!escapeChar(c, dst)) { |
42 if (c < 32 || c > 126 || c == '<' || c == '>') { | 52 if (c < 32 || c > 126 || c == '<' || c == '>') { |
43 // 1. Escaping <, > to prevent script execution. | 53 // 1. Escaping <, > to prevent script execution. |
44 // 2. Technically, we could also pass through c > 126 as UTF8, b
ut this | 54 // 2. Technically, we could also pass through c > 126 as UTF8, b
ut this |
45 // is also optional. It would also be a pain to implement her
e. | 55 // is also optional. It would also be a pain to implement her
e. |
46 unsigned symbol = static_cast<unsigned>(c); | 56 appendUnsignedAsHex(c, dst); |
47 String symbolCode = String::format("\\u%04X", symbol); | |
48 dst->append(symbolCode); | |
49 } else { | 57 } else { |
50 dst->append(c); | 58 dst->append(c); |
51 } | 59 } |
52 } | 60 } |
53 } | 61 } |
54 } | 62 } |
55 | 63 |
56 void doubleQuoteStringForJSON(const String& str, StringBuilder* dst) | 64 void doubleQuoteStringForJSON(const String16& str, String16Builder* dst) |
57 { | 65 { |
58 dst->append('"'); | 66 dst->append('"'); |
59 escapeStringForJSON(str, dst); | 67 escapeStringForJSON(str, dst); |
60 dst->append('"'); | 68 dst->append('"'); |
61 } | 69 } |
62 | 70 |
63 } // anonymous namespace | 71 } // anonymous namespace |
64 | 72 |
65 bool Value::asBoolean(bool*) const | 73 bool Value::asBoolean(bool*) const |
66 { | 74 { |
67 return false; | 75 return false; |
68 } | 76 } |
69 | 77 |
70 bool Value::asNumber(double*) const | 78 bool Value::asNumber(double*) const |
71 { | 79 { |
72 return false; | 80 return false; |
73 } | 81 } |
74 | 82 |
75 bool Value::asNumber(int*) const | 83 bool Value::asNumber(int*) const |
76 { | 84 { |
77 return false; | 85 return false; |
78 } | 86 } |
79 | 87 |
80 bool Value::asString(String*) const | 88 bool Value::asString(String16*) const |
81 { | 89 { |
82 return false; | 90 return false; |
83 } | 91 } |
84 | 92 |
85 String Value::toJSONString() const | 93 String16 Value::toJSONString() const |
86 { | 94 { |
87 StringBuilder result; | 95 String16Builder result; |
88 result.reserveCapacity(512); | 96 result.reserveCapacity(512); |
89 writeJSON(&result); | 97 writeJSON(&result); |
90 return result.toString(); | 98 return result.toString(); |
91 } | 99 } |
92 | 100 |
93 void Value::writeJSON(StringBuilder* output) const | 101 void Value::writeJSON(String16Builder* output) const |
94 { | 102 { |
95 ASSERT(m_type == TypeNull); | 103 ASSERT(m_type == TypeNull); |
96 output->append(nullString, 4); | 104 output->append(nullString, 4); |
97 } | 105 } |
98 | 106 |
99 PassOwnPtr<Value> Value::clone() const | 107 PassOwnPtr<Value> Value::clone() const |
100 { | 108 { |
101 return Value::null(); | 109 return Value::null(); |
102 } | 110 } |
103 | 111 |
(...skipping 14 matching lines...) Expand all Loading... |
118 } | 126 } |
119 | 127 |
120 bool FundamentalValue::asNumber(int* output) const | 128 bool FundamentalValue::asNumber(int* output) const |
121 { | 129 { |
122 if (type() != TypeNumber) | 130 if (type() != TypeNumber) |
123 return false; | 131 return false; |
124 *output = static_cast<int>(m_doubleValue); | 132 *output = static_cast<int>(m_doubleValue); |
125 return true; | 133 return true; |
126 } | 134 } |
127 | 135 |
128 void FundamentalValue::writeJSON(StringBuilder* output) const | 136 void FundamentalValue::writeJSON(String16Builder* output) const |
129 { | 137 { |
130 ASSERT(type() == TypeBoolean || type() == TypeNumber); | 138 ASSERT(type() == TypeBoolean || type() == TypeNumber); |
131 if (type() == TypeBoolean) { | 139 if (type() == TypeBoolean) { |
132 if (m_boolValue) | 140 if (m_boolValue) |
133 output->append(trueString, 4); | 141 output->append(trueString, 4); |
134 else | 142 else |
135 output->append(falseString, 5); | 143 output->append(falseString, 5); |
136 } else if (type() == TypeNumber) { | 144 } else if (type() == TypeNumber) { |
137 if (!std::isfinite(m_doubleValue)) { | 145 if (!std::isfinite(m_doubleValue)) { |
138 output->append(nullString, 4); | 146 output->append(nullString, 4); |
139 return; | 147 return; |
140 } | 148 } |
141 output->append(Decimal::fromDouble(m_doubleValue).toString()); | 149 output->append(String16::fromDouble(m_doubleValue)); |
142 } | 150 } |
143 } | 151 } |
144 | 152 |
145 PassOwnPtr<Value> FundamentalValue::clone() const | 153 PassOwnPtr<Value> FundamentalValue::clone() const |
146 { | 154 { |
147 return type() == TypeNumber ? FundamentalValue::create(m_doubleValue) : Fund
amentalValue::create(m_boolValue); | 155 return type() == TypeNumber ? FundamentalValue::create(m_doubleValue) : Fund
amentalValue::create(m_boolValue); |
148 } | 156 } |
149 | 157 |
150 bool StringValue::asString(String* output) const | 158 bool StringValue::asString(String16* output) const |
151 { | 159 { |
152 *output = m_stringValue; | 160 *output = m_stringValue; |
153 return true; | 161 return true; |
154 } | 162 } |
155 | 163 |
156 void StringValue::writeJSON(StringBuilder* output) const | 164 void StringValue::writeJSON(String16Builder* output) const |
157 { | 165 { |
158 ASSERT(type() == TypeString); | 166 ASSERT(type() == TypeString); |
159 doubleQuoteStringForJSON(m_stringValue, output); | 167 doubleQuoteStringForJSON(m_stringValue, output); |
160 } | 168 } |
161 | 169 |
162 PassOwnPtr<Value> StringValue::clone() const | 170 PassOwnPtr<Value> StringValue::clone() const |
163 { | 171 { |
164 return StringValue::create(m_stringValue); | 172 return StringValue::create(m_stringValue); |
165 } | 173 } |
166 | 174 |
167 DictionaryValue::~DictionaryValue() | 175 DictionaryValue::~DictionaryValue() |
168 { | 176 { |
169 } | 177 } |
170 | 178 |
171 void DictionaryValue::setBoolean(const String& name, bool value) | 179 void DictionaryValue::setBoolean(const String16& name, bool value) |
172 { | 180 { |
173 setValue(name, FundamentalValue::create(value)); | 181 setValue(name, FundamentalValue::create(value)); |
174 } | 182 } |
175 | 183 |
176 void DictionaryValue::setNumber(const String& name, double value) | 184 void DictionaryValue::setNumber(const String16& name, double value) |
177 { | 185 { |
178 setValue(name, FundamentalValue::create(value)); | 186 setValue(name, FundamentalValue::create(value)); |
179 } | 187 } |
180 | 188 |
181 void DictionaryValue::setString(const String& name, const String& value) | 189 void DictionaryValue::setString(const String16& name, const String16& value) |
182 { | 190 { |
183 setValue(name, StringValue::create(value)); | 191 setValue(name, StringValue::create(value)); |
184 } | 192 } |
185 | 193 |
186 void DictionaryValue::setValue(const String& name, PassOwnPtr<Value> value) | 194 void DictionaryValue::setValue(const String16& name, PassOwnPtr<Value> value) |
187 { | 195 { |
188 ASSERT(value); | 196 ASSERT(value); |
189 if (m_data.set(name, value)) | 197 if (m_data.set(name, value)) |
190 m_order.append(name); | 198 m_order.append(name); |
191 } | 199 } |
192 | 200 |
193 void DictionaryValue::setObject(const String& name, PassOwnPtr<DictionaryValue>
value) | 201 void DictionaryValue::setObject(const String16& name, PassOwnPtr<DictionaryValue
> value) |
194 { | 202 { |
195 ASSERT(value); | 203 ASSERT(value); |
196 if (m_data.set(name, value)) | 204 if (m_data.set(name, value)) |
197 m_order.append(name); | 205 m_order.append(name); |
198 } | 206 } |
199 | 207 |
200 void DictionaryValue::setArray(const String& name, PassOwnPtr<ListValue> value) | 208 void DictionaryValue::setArray(const String16& name, PassOwnPtr<ListValue> value
) |
201 { | 209 { |
202 ASSERT(value); | 210 ASSERT(value); |
203 if (m_data.set(name, value)) | 211 if (m_data.set(name, value)) |
204 m_order.append(name); | 212 m_order.append(name); |
205 } | 213 } |
206 | 214 |
207 bool DictionaryValue::getBoolean(const String& name, bool* output) const | 215 bool DictionaryValue::getBoolean(const String16& name, bool* output) const |
208 { | 216 { |
209 protocol::Value* value = get(name); | 217 protocol::Value* value = get(name); |
210 if (!value) | 218 if (!value) |
211 return false; | 219 return false; |
212 return value->asBoolean(output); | 220 return value->asBoolean(output); |
213 } | 221 } |
214 | 222 |
215 bool DictionaryValue::getString(const String& name, String* output) const | 223 bool DictionaryValue::getString(const String16& name, String16* output) const |
216 { | 224 { |
217 protocol::Value* value = get(name); | 225 protocol::Value* value = get(name); |
218 if (!value) | 226 if (!value) |
219 return false; | 227 return false; |
220 return value->asString(output); | 228 return value->asString(output); |
221 } | 229 } |
222 | 230 |
223 DictionaryValue* DictionaryValue::getObject(const String& name) const | 231 DictionaryValue* DictionaryValue::getObject(const String16& name) const |
224 { | 232 { |
225 return DictionaryValue::cast(get(name)); | 233 return DictionaryValue::cast(get(name)); |
226 } | 234 } |
227 | 235 |
228 protocol::ListValue* DictionaryValue::getArray(const String& name) const | 236 protocol::ListValue* DictionaryValue::getArray(const String16& name) const |
229 { | 237 { |
230 return ListValue::cast(get(name)); | 238 return ListValue::cast(get(name)); |
231 } | 239 } |
232 | 240 |
233 protocol::Value* DictionaryValue::get(const String& name) const | 241 protocol::Value* DictionaryValue::get(const String16& name) const |
234 { | 242 { |
235 Dictionary::const_iterator it = m_data.find(name); | 243 Dictionary::const_iterator it = m_data.find(name); |
236 if (it == m_data.end()) | 244 if (it == m_data.end()) |
237 return nullptr; | 245 return nullptr; |
238 return it->second; | 246 return it->second; |
239 } | 247 } |
240 | 248 |
241 DictionaryValue::Entry DictionaryValue::at(size_t index) const | 249 DictionaryValue::Entry DictionaryValue::at(size_t index) const |
242 { | 250 { |
243 String key = m_order[index]; | 251 String16 key = m_order[index]; |
244 return std::make_pair(key, m_data.get(key)); | 252 return std::make_pair(key, m_data.get(key)); |
245 } | 253 } |
246 | 254 |
247 bool DictionaryValue::booleanProperty(const String& name, bool defaultValue) con
st | 255 bool DictionaryValue::booleanProperty(const String16& name, bool defaultValue) c
onst |
248 { | 256 { |
249 bool result = defaultValue; | 257 bool result = defaultValue; |
250 getBoolean(name, &result); | 258 getBoolean(name, &result); |
251 return result; | 259 return result; |
252 } | 260 } |
253 | 261 |
254 void DictionaryValue::remove(const String& name) | 262 void DictionaryValue::remove(const String16& name) |
255 { | 263 { |
256 m_data.remove(name); | 264 m_data.remove(name); |
257 for (size_t i = 0; i < m_order.size(); ++i) { | 265 for (size_t i = 0; i < m_order.size(); ++i) { |
258 if (m_order[i] == name) { | 266 if (m_order[i] == name) { |
259 m_order.remove(i); | 267 m_order.remove(i); |
260 break; | 268 break; |
261 } | 269 } |
262 } | 270 } |
263 } | 271 } |
264 | 272 |
265 void DictionaryValue::writeJSON(StringBuilder* output) const | 273 void DictionaryValue::writeJSON(String16Builder* output) const |
266 { | 274 { |
267 output->append('{'); | 275 output->append('{'); |
268 for (size_t i = 0; i < m_order.size(); ++i) { | 276 for (size_t i = 0; i < m_order.size(); ++i) { |
269 Dictionary::const_iterator it = m_data.find(m_order[i]); | 277 Dictionary::const_iterator it = m_data.find(m_order[i]); |
270 ASSERT_WITH_SECURITY_IMPLICATION(it != m_data.end()); | 278 ASSERT_WITH_SECURITY_IMPLICATION(it != m_data.end()); |
271 if (i) | 279 if (i) |
272 output->append(','); | 280 output->append(','); |
273 doubleQuoteStringForJSON(it->first, output); | 281 doubleQuoteStringForJSON(it->first, output); |
274 output->append(':'); | 282 output->append(':'); |
275 it->second->writeJSON(output); | 283 it->second->writeJSON(output); |
276 } | 284 } |
277 output->append('}'); | 285 output->append('}'); |
278 } | 286 } |
279 | 287 |
280 PassOwnPtr<Value> DictionaryValue::clone() const | 288 PassOwnPtr<Value> DictionaryValue::clone() const |
281 { | 289 { |
282 OwnPtr<DictionaryValue> result = DictionaryValue::create(); | 290 OwnPtr<DictionaryValue> result = DictionaryValue::create(); |
283 for (size_t i = 0; i < m_order.size(); ++i) { | 291 for (size_t i = 0; i < m_order.size(); ++i) { |
284 String key = m_order[i]; | 292 String16 key = m_order[i]; |
285 Value* value = m_data.get(key); | 293 Value* value = m_data.get(key); |
286 ASSERT(value); | 294 ASSERT(value); |
287 result->setValue(key, value->clone()); | 295 result->setValue(key, value->clone()); |
288 } | 296 } |
289 return result.release(); | 297 return result.release(); |
290 } | 298 } |
291 | 299 |
292 DictionaryValue::DictionaryValue() | 300 DictionaryValue::DictionaryValue() |
293 : Value(TypeObject) | 301 : Value(TypeObject) |
294 { | 302 { |
295 } | 303 } |
296 | 304 |
297 ListValue::~ListValue() | 305 ListValue::~ListValue() |
298 { | 306 { |
299 } | 307 } |
300 | 308 |
301 void ListValue::writeJSON(StringBuilder* output) const | 309 void ListValue::writeJSON(String16Builder* output) const |
302 { | 310 { |
303 output->append('['); | 311 output->append('['); |
304 for (Vector<OwnPtr<protocol::Value>>::const_iterator it = m_data.begin(); it
!= m_data.end(); ++it) { | 312 for (Vector<OwnPtr<protocol::Value>>::const_iterator it = m_data.begin(); it
!= m_data.end(); ++it) { |
305 if (it != m_data.begin()) | 313 if (it != m_data.begin()) |
306 output->append(','); | 314 output->append(','); |
307 (*it)->writeJSON(output); | 315 (*it)->writeJSON(output); |
308 } | 316 } |
309 output->append(']'); | 317 output->append(']'); |
310 } | 318 } |
311 | 319 |
(...skipping 17 matching lines...) Expand all Loading... |
329 } | 337 } |
330 | 338 |
331 protocol::Value* ListValue::at(size_t index) | 339 protocol::Value* ListValue::at(size_t index) |
332 { | 340 { |
333 ASSERT_WITH_SECURITY_IMPLICATION(index < m_data.size()); | 341 ASSERT_WITH_SECURITY_IMPLICATION(index < m_data.size()); |
334 return m_data[index].get(); | 342 return m_data[index].get(); |
335 } | 343 } |
336 | 344 |
337 } // namespace protocol | 345 } // namespace protocol |
338 } // namespace blink | 346 } // namespace blink |
OLD | NEW |