| 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/Parser.h" | 5 #include "platform/inspector_protocol/Parser.h" |
| 6 | 6 |
| 7 #include "platform/Decimal.h" | 7 #include "platform/inspector_protocol/String16.h" |
| 8 #include "platform/inspector_protocol/Values.h" | 8 #include "platform/inspector_protocol/Values.h" |
| 9 #include "wtf/text/StringBuilder.h" | |
| 10 #include "wtf/text/UTF8.h" | |
| 11 | 9 |
| 12 namespace blink { | 10 namespace blink { |
| 13 namespace protocol { | 11 namespace protocol { |
| 14 | 12 |
| 15 namespace { | 13 namespace { |
| 16 | 14 |
| 17 const int stackLimit = 1000; | 15 const int stackLimit = 1000; |
| 18 | 16 |
| 19 enum Token { | 17 enum Token { |
| 20 ObjectBegin, | 18 ObjectBegin, |
| (...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 292 return c - '0'; | 290 return c - '0'; |
| 293 if ('A' <= c && c <= 'F') | 291 if ('A' <= c && c <= 'F') |
| 294 return c - 'A' + 10; | 292 return c - 'A' + 10; |
| 295 if ('a' <= c && c <= 'f') | 293 if ('a' <= c && c <= 'f') |
| 296 return c - 'a' + 10; | 294 return c - 'a' + 10; |
| 297 ASSERT_NOT_REACHED(); | 295 ASSERT_NOT_REACHED(); |
| 298 return 0; | 296 return 0; |
| 299 } | 297 } |
| 300 | 298 |
| 301 template<typename CharType> | 299 template<typename CharType> |
| 302 bool decodeUTF8(const CharType* start, const CharType* end, const CharType** utf
8charEnd, StringBuilder* output) | 300 bool decodeUTF8(const CharType* start, const CharType* end, const CharType** utf
8charEnd, String16Builder* output) |
| 303 { | 301 { |
| 304 UChar utf16[4] = {0}; | 302 UChar utf16[4] = {0}; |
| 305 char utf8[6] = {0}; | 303 char utf8[6] = {0}; |
| 306 size_t utf8count = 0; | 304 size_t utf8count = 0; |
| 307 | 305 |
| 308 while (start < end) { | 306 while (start < end) { |
| 309 if (start + 1 >= end || *start != '\\' || *(start + 1) != 'x') | 307 if (start + 1 >= end || *start != '\\' || *(start + 1) != 'x') |
| 310 return false; | 308 return false; |
| 311 start += 2; | 309 start += 2; |
| 312 | 310 |
| 313 // Accumulate one more utf8 character and try converting to utf16. | 311 // Accumulate one more utf8 character and try converting to utf16. |
| 314 if (start + 1 >= end) | 312 if (start + 1 >= end) |
| 315 return false; | 313 return false; |
| 316 utf8[utf8count++] = (hexToInt(*start) << 4) + hexToInt(*(start + 1)); | 314 utf8[utf8count++] = (hexToInt(*start) << 4) + hexToInt(*(start + 1)); |
| 317 start += 2; | 315 start += 2; |
| 318 | 316 |
| 319 const char* utf8start = utf8; | 317 const char* utf8start = utf8; |
| 320 UChar* utf16start = utf16; | 318 UChar* utf16start = utf16; |
| 321 WTF::Unicode::ConversionResult conversionResult = WTF::Unicode::convertU
TF8ToUTF16(&utf8start, utf8start + utf8count, &utf16start, utf16start + WTF_ARRA
Y_LENGTH(utf16), nullptr, true); | 319 String16::ConversionResult conversionResult = String16::convertUTF8ToUTF
16(&utf8start, utf8start + utf8count, &utf16start, utf16start + 4, nullptr, true
); |
| 322 | 320 |
| 323 if (conversionResult == WTF::Unicode::sourceIllegal) | 321 if (conversionResult == String16::sourceIllegal) |
| 324 return false; | 322 return false; |
| 325 | 323 |
| 326 if (conversionResult == WTF::Unicode::conversionOK) { | 324 if (conversionResult == String16::conversionOK) { |
| 327 // Not all utf8 characters were consumed - failed parsing. | 325 // Not all utf8 characters were consumed - failed parsing. |
| 328 if (utf8start != utf8 + utf8count) | 326 if (utf8start != utf8 + utf8count) |
| 329 return false; | 327 return false; |
| 330 | 328 |
| 331 size_t utf16length = utf16start - utf16; | 329 size_t utf16length = utf16start - utf16; |
| 332 output->append(utf16, utf16length); | 330 output->append(utf16, utf16length); |
| 333 *utf8charEnd = start; | 331 *utf8charEnd = start; |
| 334 return true; | 332 return true; |
| 335 } | 333 } |
| 336 | 334 |
| 337 // Keep accumulating utf8 characters up to buffer length (6 should be en
ough). | 335 // Keep accumulating utf8 characters up to buffer length (6 should be en
ough). |
| 338 if (utf8count >= WTF_ARRAY_LENGTH(utf8)) | 336 if (utf8count >= 6) |
| 339 return false; | 337 return false; |
| 340 } | 338 } |
| 341 | 339 |
| 342 return false; | 340 return false; |
| 343 } | 341 } |
| 344 | 342 |
| 345 template<typename CharType> | 343 template<typename CharType> |
| 346 bool decodeString(const CharType* start, const CharType* end, StringBuilder* out
put) | 344 bool decodeString(const CharType* start, const CharType* end, String16Builder* o
utput) |
| 347 { | 345 { |
| 348 while (start < end) { | 346 while (start < end) { |
| 349 UChar c = *start++; | 347 UChar c = *start++; |
| 350 if ('\\' != c) { | 348 if ('\\' != c) { |
| 351 output->append(c); | 349 output->append(c); |
| 352 continue; | 350 continue; |
| 353 } | 351 } |
| 354 c = *start++; | 352 c = *start++; |
| 355 | 353 |
| 356 if (c == 'x') { | 354 if (c == 'x') { |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 392 break; | 390 break; |
| 393 default: | 391 default: |
| 394 return false; | 392 return false; |
| 395 } | 393 } |
| 396 output->append(c); | 394 output->append(c); |
| 397 } | 395 } |
| 398 return true; | 396 return true; |
| 399 } | 397 } |
| 400 | 398 |
| 401 template<typename CharType> | 399 template<typename CharType> |
| 402 bool decodeString(const CharType* start, const CharType* end, String* output) | 400 bool decodeString(const CharType* start, const CharType* end, String16* output) |
| 403 { | 401 { |
| 404 if (start == end) { | 402 if (start == end) { |
| 405 *output = ""; | 403 *output = ""; |
| 406 return true; | 404 return true; |
| 407 } | 405 } |
| 408 if (start > end) | 406 if (start > end) |
| 409 return false; | 407 return false; |
| 410 StringBuilder buffer; | 408 String16Builder buffer; |
| 411 buffer.reserveCapacity(end - start); | 409 buffer.reserveCapacity(end - start); |
| 412 if (!decodeString(start, end, &buffer)) | 410 if (!decodeString(start, end, &buffer)) |
| 413 return false; | 411 return false; |
| 414 *output = buffer.toString(); | 412 *output = buffer.toString(); |
| 415 // Validate constructed utf16 string. | 413 // Validate constructed utf16 string. |
| 416 if (output->utf8(StrictUTF8Conversion).isNull()) | 414 if (!output->validateUTF8()) |
| 417 return false; | 415 return false; |
| 418 return true; | 416 return true; |
| 419 } | 417 } |
| 420 | 418 |
| 421 template<typename CharType> | 419 template<typename CharType> |
| 422 PassOwnPtr<Value> buildValue(const CharType* start, const CharType* end, const C
harType** valueTokenEnd, int depth) | 420 PassOwnPtr<Value> buildValue(const CharType* start, const CharType* end, const C
harType** valueTokenEnd, int depth) |
| 423 { | 421 { |
| 424 if (depth > stackLimit) | 422 if (depth > stackLimit) |
| 425 return nullptr; | 423 return nullptr; |
| 426 | 424 |
| 427 OwnPtr<Value> result; | 425 OwnPtr<Value> result; |
| 428 const CharType* tokenStart; | 426 const CharType* tokenStart; |
| 429 const CharType* tokenEnd; | 427 const CharType* tokenEnd; |
| 430 Token token = parseToken(start, end, &tokenStart, &tokenEnd); | 428 Token token = parseToken(start, end, &tokenStart, &tokenEnd); |
| 431 switch (token) { | 429 switch (token) { |
| 432 case InvalidToken: | 430 case InvalidToken: |
| 433 return nullptr; | 431 return nullptr; |
| 434 case NullToken: | 432 case NullToken: |
| 435 result = Value::null(); | 433 result = Value::null(); |
| 436 break; | 434 break; |
| 437 case BoolTrue: | 435 case BoolTrue: |
| 438 result = FundamentalValue::create(true); | 436 result = FundamentalValue::create(true); |
| 439 break; | 437 break; |
| 440 case BoolFalse: | 438 case BoolFalse: |
| 441 result = FundamentalValue::create(false); | 439 result = FundamentalValue::create(false); |
| 442 break; | 440 break; |
| 443 case Number: { | 441 case Number: { |
| 444 bool ok; | 442 bool ok; |
| 445 double value = charactersToDouble(tokenStart, tokenEnd - tokenStart, &ok
); | 443 double value = String16::charactersToDouble(tokenStart, tokenEnd - token
Start, &ok); |
| 446 if (Decimal::fromDouble(value).isInfinity()) | |
| 447 ok = false; | |
| 448 if (!ok) | 444 if (!ok) |
| 449 return nullptr; | 445 return nullptr; |
| 450 result = FundamentalValue::create(value); | 446 result = FundamentalValue::create(value); |
| 451 break; | 447 break; |
| 452 } | 448 } |
| 453 case StringLiteral: { | 449 case StringLiteral: { |
| 454 String value; | 450 String16 value; |
| 455 bool ok = decodeString(tokenStart + 1, tokenEnd - 1, &value); | 451 bool ok = decodeString(tokenStart + 1, tokenEnd - 1, &value); |
| 456 if (!ok) | 452 if (!ok) |
| 457 return nullptr; | 453 return nullptr; |
| 458 result = StringValue::create(value); | 454 result = StringValue::create(value); |
| 459 break; | 455 break; |
| 460 } | 456 } |
| 461 case ArrayBegin: { | 457 case ArrayBegin: { |
| 462 OwnPtr<ListValue> array = ListValue::create(); | 458 OwnPtr<ListValue> array = ListValue::create(); |
| 463 start = tokenEnd; | 459 start = tokenEnd; |
| 464 token = parseToken(start, end, &tokenStart, &tokenEnd); | 460 token = parseToken(start, end, &tokenStart, &tokenEnd); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 486 result = array.release(); | 482 result = array.release(); |
| 487 break; | 483 break; |
| 488 } | 484 } |
| 489 case ObjectBegin: { | 485 case ObjectBegin: { |
| 490 OwnPtr<DictionaryValue> object = DictionaryValue::create(); | 486 OwnPtr<DictionaryValue> object = DictionaryValue::create(); |
| 491 start = tokenEnd; | 487 start = tokenEnd; |
| 492 token = parseToken(start, end, &tokenStart, &tokenEnd); | 488 token = parseToken(start, end, &tokenStart, &tokenEnd); |
| 493 while (token != ObjectEnd) { | 489 while (token != ObjectEnd) { |
| 494 if (token != StringLiteral) | 490 if (token != StringLiteral) |
| 495 return nullptr; | 491 return nullptr; |
| 496 String key; | 492 String16 key; |
| 497 if (!decodeString(tokenStart + 1, tokenEnd - 1, &key)) | 493 if (!decodeString(tokenStart + 1, tokenEnd - 1, &key)) |
| 498 return nullptr; | 494 return nullptr; |
| 499 start = tokenEnd; | 495 start = tokenEnd; |
| 500 | 496 |
| 501 token = parseToken(start, end, &tokenStart, &tokenEnd); | 497 token = parseToken(start, end, &tokenStart, &tokenEnd); |
| 502 if (token != ObjectPairSeparator) | 498 if (token != ObjectPairSeparator) |
| 503 return nullptr; | 499 return nullptr; |
| 504 start = tokenEnd; | 500 start = tokenEnd; |
| 505 | 501 |
| 506 OwnPtr<Value> value = buildValue(start, end, &tokenEnd, depth + 1); | 502 OwnPtr<Value> value = buildValue(start, end, &tokenEnd, depth + 1); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 543 const CharType* end = start + length; | 539 const CharType* end = start + length; |
| 544 const CharType *tokenEnd; | 540 const CharType *tokenEnd; |
| 545 OwnPtr<Value> value = buildValue(start, end, &tokenEnd, 0); | 541 OwnPtr<Value> value = buildValue(start, end, &tokenEnd, 0); |
| 546 if (!value || tokenEnd != end) | 542 if (!value || tokenEnd != end) |
| 547 return nullptr; | 543 return nullptr; |
| 548 return value.release(); | 544 return value.release(); |
| 549 } | 545 } |
| 550 | 546 |
| 551 } // anonymous namespace | 547 } // anonymous namespace |
| 552 | 548 |
| 553 PassOwnPtr<Value> parseJSON(const String& json) | 549 PassOwnPtr<Value> parseJSON(const String16& json) |
| 554 { | 550 { |
| 555 if (json.isEmpty()) | 551 if (json.isEmpty()) |
| 556 return nullptr; | 552 return nullptr; |
| 557 if (json.is8Bit()) | 553 if (json.is8Bit()) |
| 558 return parseJSONInternal(json.characters8(), json.length()); | 554 return parseJSONInternal(json.characters8(), json.length()); |
| 559 return parseJSONInternal(json.characters16(), json.length()); | 555 return parseJSONInternal(json.characters16(), json.length()); |
| 560 } | 556 } |
| 561 | 557 |
| 562 } // namespace protocol | 558 } // namespace protocol |
| 563 } // namespace blink | 559 } // namespace blink |
| OLD | NEW |