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