| 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/Decimal.h" |
| 8 #include "platform/inspector_protocol/Values.h" | 8 #include "platform/inspector_protocol/Values.h" |
| 9 #include "wtf/text/StringBuilder.h" | 9 #include "wtf/text/StringBuilder.h" |
| 10 #include "wtf/text/UTF8.h" | 10 #include "wtf/text/UTF8.h" |
| (...skipping 401 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 412 if (!decodeString(start, end, &buffer)) | 412 if (!decodeString(start, end, &buffer)) |
| 413 return false; | 413 return false; |
| 414 *output = buffer.toString(); | 414 *output = buffer.toString(); |
| 415 // Validate constructed utf16 string. | 415 // Validate constructed utf16 string. |
| 416 if (output->utf8(StrictUTF8Conversion).isNull()) | 416 if (output->utf8(StrictUTF8Conversion).isNull()) |
| 417 return false; | 417 return false; |
| 418 return true; | 418 return true; |
| 419 } | 419 } |
| 420 | 420 |
| 421 template<typename CharType> | 421 template<typename CharType> |
| 422 PassRefPtr<Value> buildValue(const CharType* start, const CharType* end, const C
harType** valueTokenEnd, int depth) | 422 PassOwnPtr<Value> buildValue(const CharType* start, const CharType* end, const C
harType** valueTokenEnd, int depth) |
| 423 { | 423 { |
| 424 if (depth > stackLimit) | 424 if (depth > stackLimit) |
| 425 return nullptr; | 425 return nullptr; |
| 426 | 426 |
| 427 RefPtr<Value> result; | 427 OwnPtr<Value> result; |
| 428 const CharType* tokenStart; | 428 const CharType* tokenStart; |
| 429 const CharType* tokenEnd; | 429 const CharType* tokenEnd; |
| 430 Token token = parseToken(start, end, &tokenStart, &tokenEnd); | 430 Token token = parseToken(start, end, &tokenStart, &tokenEnd); |
| 431 switch (token) { | 431 switch (token) { |
| 432 case InvalidToken: | 432 case InvalidToken: |
| 433 return nullptr; | 433 return nullptr; |
| 434 case NullToken: | 434 case NullToken: |
| 435 result = Value::null(); | 435 result = Value::null(); |
| 436 break; | 436 break; |
| 437 case BoolTrue: | 437 case BoolTrue: |
| (...skipping 14 matching lines...) Expand all Loading... |
| 452 } | 452 } |
| 453 case StringLiteral: { | 453 case StringLiteral: { |
| 454 String value; | 454 String value; |
| 455 bool ok = decodeString(tokenStart + 1, tokenEnd - 1, &value); | 455 bool ok = decodeString(tokenStart + 1, tokenEnd - 1, &value); |
| 456 if (!ok) | 456 if (!ok) |
| 457 return nullptr; | 457 return nullptr; |
| 458 result = StringValue::create(value); | 458 result = StringValue::create(value); |
| 459 break; | 459 break; |
| 460 } | 460 } |
| 461 case ArrayBegin: { | 461 case ArrayBegin: { |
| 462 RefPtr<ListValue> array = ListValue::create(); | 462 OwnPtr<ListValue> array = ListValue::create(); |
| 463 start = tokenEnd; | 463 start = tokenEnd; |
| 464 token = parseToken(start, end, &tokenStart, &tokenEnd); | 464 token = parseToken(start, end, &tokenStart, &tokenEnd); |
| 465 while (token != ArrayEnd) { | 465 while (token != ArrayEnd) { |
| 466 RefPtr<Value> arrayNode = buildValue(start, end, &tokenEnd, depth +
1); | 466 OwnPtr<Value> arrayNode = buildValue(start, end, &tokenEnd, depth +
1); |
| 467 if (!arrayNode) | 467 if (!arrayNode) |
| 468 return nullptr; | 468 return nullptr; |
| 469 array->pushValue(arrayNode); | 469 array->pushValue(arrayNode.release()); |
| 470 | 470 |
| 471 // After a list value, we expect a comma or the end of the list. | 471 // After a list value, we expect a comma or the end of the list. |
| 472 start = tokenEnd; | 472 start = tokenEnd; |
| 473 token = parseToken(start, end, &tokenStart, &tokenEnd); | 473 token = parseToken(start, end, &tokenStart, &tokenEnd); |
| 474 if (token == ListSeparator) { | 474 if (token == ListSeparator) { |
| 475 start = tokenEnd; | 475 start = tokenEnd; |
| 476 token = parseToken(start, end, &tokenStart, &tokenEnd); | 476 token = parseToken(start, end, &tokenStart, &tokenEnd); |
| 477 if (token == ArrayEnd) | 477 if (token == ArrayEnd) |
| 478 return nullptr; | 478 return nullptr; |
| 479 } else if (token != ArrayEnd) { | 479 } else if (token != ArrayEnd) { |
| 480 // Unexpected value after list value. Bail out. | 480 // Unexpected value after list value. Bail out. |
| 481 return nullptr; | 481 return nullptr; |
| 482 } | 482 } |
| 483 } | 483 } |
| 484 if (token != ArrayEnd) | 484 if (token != ArrayEnd) |
| 485 return nullptr; | 485 return nullptr; |
| 486 result = array.release(); | 486 result = array.release(); |
| 487 break; | 487 break; |
| 488 } | 488 } |
| 489 case ObjectBegin: { | 489 case ObjectBegin: { |
| 490 RefPtr<DictionaryValue> object = DictionaryValue::create(); | 490 OwnPtr<DictionaryValue> object = DictionaryValue::create(); |
| 491 start = tokenEnd; | 491 start = tokenEnd; |
| 492 token = parseToken(start, end, &tokenStart, &tokenEnd); | 492 token = parseToken(start, end, &tokenStart, &tokenEnd); |
| 493 while (token != ObjectEnd) { | 493 while (token != ObjectEnd) { |
| 494 if (token != StringLiteral) | 494 if (token != StringLiteral) |
| 495 return nullptr; | 495 return nullptr; |
| 496 String key; | 496 String key; |
| 497 if (!decodeString(tokenStart + 1, tokenEnd - 1, &key)) | 497 if (!decodeString(tokenStart + 1, tokenEnd - 1, &key)) |
| 498 return nullptr; | 498 return nullptr; |
| 499 start = tokenEnd; | 499 start = tokenEnd; |
| 500 | 500 |
| 501 token = parseToken(start, end, &tokenStart, &tokenEnd); | 501 token = parseToken(start, end, &tokenStart, &tokenEnd); |
| 502 if (token != ObjectPairSeparator) | 502 if (token != ObjectPairSeparator) |
| 503 return nullptr; | 503 return nullptr; |
| 504 start = tokenEnd; | 504 start = tokenEnd; |
| 505 | 505 |
| 506 RefPtr<Value> value = buildValue(start, end, &tokenEnd, depth + 1); | 506 OwnPtr<Value> value = buildValue(start, end, &tokenEnd, depth + 1); |
| 507 if (!value) | 507 if (!value) |
| 508 return nullptr; | 508 return nullptr; |
| 509 object->setValue(key, value); | 509 object->setValue(key, value.release()); |
| 510 start = tokenEnd; | 510 start = tokenEnd; |
| 511 | 511 |
| 512 // After a key/value pair, we expect a comma or the end of the | 512 // After a key/value pair, we expect a comma or the end of the |
| 513 // object. | 513 // object. |
| 514 token = parseToken(start, end, &tokenStart, &tokenEnd); | 514 token = parseToken(start, end, &tokenStart, &tokenEnd); |
| 515 if (token == ListSeparator) { | 515 if (token == ListSeparator) { |
| 516 start = tokenEnd; | 516 start = tokenEnd; |
| 517 token = parseToken(start, end, &tokenStart, &tokenEnd); | 517 token = parseToken(start, end, &tokenStart, &tokenEnd); |
| 518 if (token == ObjectEnd) | 518 if (token == ObjectEnd) |
| 519 return nullptr; | 519 return nullptr; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 531 default: | 531 default: |
| 532 // We got a token that's not a value. | 532 // We got a token that's not a value. |
| 533 return nullptr; | 533 return nullptr; |
| 534 } | 534 } |
| 535 | 535 |
| 536 skipWhitespaceAndComments(tokenEnd, end, valueTokenEnd); | 536 skipWhitespaceAndComments(tokenEnd, end, valueTokenEnd); |
| 537 return result.release(); | 537 return result.release(); |
| 538 } | 538 } |
| 539 | 539 |
| 540 template<typename CharType> | 540 template<typename CharType> |
| 541 PassRefPtr<Value> parseJSONInternal(const CharType* start, unsigned length) | 541 PassOwnPtr<Value> parseJSONInternal(const CharType* start, unsigned length) |
| 542 { | 542 { |
| 543 const CharType* end = start + length; | 543 const CharType* end = start + length; |
| 544 const CharType *tokenEnd; | 544 const CharType *tokenEnd; |
| 545 RefPtr<Value> value = buildValue(start, end, &tokenEnd, 0); | 545 OwnPtr<Value> value = buildValue(start, end, &tokenEnd, 0); |
| 546 if (!value || tokenEnd != end) | 546 if (!value || tokenEnd != end) |
| 547 return nullptr; | 547 return nullptr; |
| 548 return value.release(); | 548 return value.release(); |
| 549 } | 549 } |
| 550 | 550 |
| 551 } // anonymous namespace | 551 } // anonymous namespace |
| 552 | 552 |
| 553 PassRefPtr<Value> parseJSON(const String& json) | 553 PassOwnPtr<Value> parseJSON(const String& json) |
| 554 { | 554 { |
| 555 if (json.isEmpty()) | 555 if (json.isEmpty()) |
| 556 return nullptr; | 556 return nullptr; |
| 557 if (json.is8Bit()) | 557 if (json.is8Bit()) |
| 558 return parseJSONInternal(json.characters8(), json.length()); | 558 return parseJSONInternal(json.characters8(), json.length()); |
| 559 return parseJSONInternal(json.characters16(), json.length()); | 559 return parseJSONInternal(json.characters16(), json.length()); |
| 560 } | 560 } |
| 561 | 561 |
| 562 } // namespace protocol | 562 } // namespace protocol |
| 563 } // namespace blink | 563 } // namespace blink |
| OLD | NEW |