Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "platform/json.h" | 5 #include "platform/json.h" |
| 6 | 6 |
| 7 #include "platform/assert.h" | 7 #include "platform/assert.h" |
| 8 #include "platform/globals.h" | 8 #include "platform/globals.h" |
| 9 #include "platform/utils.h" | 9 #include "platform/utils.h" |
| 10 #include "vm/os.h" | 10 #include "vm/os.h" |
| (...skipping 624 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 635 | 635 |
| 636 | 636 |
| 637 void TextBuffer::AddEscapedString(const char* s) { | 637 void TextBuffer::AddEscapedString(const char* s) { |
| 638 intptr_t len = strlen(s); | 638 intptr_t len = strlen(s); |
| 639 for (int i = 0; i < len; i++) { | 639 for (int i = 0; i < len; i++) { |
| 640 AddEscapedChar(s[i]); | 640 AddEscapedChar(s[i]); |
| 641 } | 641 } |
| 642 } | 642 } |
| 643 | 643 |
| 644 | 644 |
| 645 void TextBuffer::AddEscapedUTF8String(const char* s) { | |
| 646 intptr_t len = strlen(s); | |
| 647 const uint8_t* s8 = reinterpret_cast<const uint8_t*>(s); | |
| 648 intptr_t i = 0; | |
| 649 for (; i < len; ) { | |
| 650 // Extract next UTF8 character. | |
| 651 uint32_t ch = 0; | |
| 652 uint32_t ch_len = Utf8Decode(&s8[i], len - i, &ch); | |
| 653 ASSERT(ch_len != 0); | |
| 654 AddEscapedChar(ch); | |
| 655 // Move i forward. | |
| 656 i += ch_len; | |
| 657 } | |
| 658 ASSERT(i == len); | |
| 659 } | |
| 660 | |
| 661 | |
| 645 void TextBuffer::EnsureCapacity(intptr_t len) { | 662 void TextBuffer::EnsureCapacity(intptr_t len) { |
| 646 intptr_t remaining = buf_size_ - msg_len_; | 663 intptr_t remaining = buf_size_ - msg_len_; |
| 647 if (remaining <= len) { | 664 if (remaining <= len) { |
| 648 const int kBufferSpareCapacity = 64; // Somewhat arbitrary. | 665 const int kBufferSpareCapacity = 64; // Somewhat arbitrary. |
| 649 // TODO(turnidge): do we need to guard against overflow or other | 666 // TODO(turnidge): do we need to guard against overflow or other |
| 650 // security issues here? Text buffers are used by the debugger | 667 // security issues here? Text buffers are used by the debugger |
| 651 // to send user-controlled data (e.g. values of string variables) to | 668 // to send user-controlled data (e.g. values of string variables) to |
| 652 // the debugger front-end. | 669 // the debugger front-end. |
| 653 intptr_t new_size = buf_size_ + len + kBufferSpareCapacity; | 670 intptr_t new_size = buf_size_ + len + kBufferSpareCapacity; |
| 654 char* new_buf = reinterpret_cast<char*>(realloc(buf_, new_size)); | 671 char* new_buf = reinterpret_cast<char*>(realloc(buf_, new_size)); |
| 655 ASSERT(new_buf != NULL); | 672 ASSERT(new_buf != NULL); |
| 656 buf_ = new_buf; | 673 buf_ = new_buf; |
| 657 buf_size_ = new_size; | 674 buf_size_ = new_size; |
| 658 } | 675 } |
| 659 } | 676 } |
| 660 | 677 |
| 678 | |
| 679 static const uint32_t kMaxCodePoint = 0x10FFFF; | |
|
turnidge
2014/03/10 21:03:28
I don't like duplicating the existing unicode deco
| |
| 680 | |
| 681 | |
| 682 static const int8_t kTrailBytes[256] = { | |
| 683 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | |
| 684 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | |
| 685 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | |
| 686 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | |
| 687 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | |
| 688 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | |
| 689 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | |
| 690 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | |
| 691 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
| 692 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
| 693 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
| 694 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
| 695 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | |
| 696 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | |
| 697 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, | |
| 698 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 0, 0 | |
| 699 }; | |
| 700 | |
| 701 | |
| 702 static const uint32_t kMagicBits[7] = { | |
| 703 0, // Padding. | |
| 704 0x00000000, | |
| 705 0x00003080, | |
| 706 0x000E2080, | |
| 707 0x03C82080, | |
| 708 0xFA082080, | |
| 709 0x82082080 | |
| 710 }; | |
| 711 | |
| 712 | |
| 713 // Minimum values of code points used to check shortest form. | |
| 714 static const uint32_t kOverlongMinimum[7] = { | |
| 715 0, // Padding. | |
| 716 0x0, | |
| 717 0x80, | |
| 718 0x800, | |
| 719 0x10000, | |
| 720 0xFFFFFFFF, | |
| 721 0xFFFFFFFF | |
| 722 }; | |
| 723 | |
| 724 | |
| 725 static bool IsTrailByte(uint8_t code_unit) { | |
| 726 return (code_unit & 0xC0) == 0x80; | |
| 727 } | |
| 728 | |
| 729 static bool IsOutOfRange(uint32_t code_point) { | |
| 730 return code_point > kMaxCodePoint; | |
| 731 } | |
| 732 | |
| 733 | |
| 734 static bool IsNonShortestForm(uint32_t code_point, size_t num_code_units) { | |
| 735 return code_point < kOverlongMinimum[num_code_units]; | |
| 736 } | |
| 737 | |
| 738 static bool IsSurrogate(int32_t ch) { | |
| 739 return (ch & 0xFFFFF800) == 0xD800; | |
| 740 } | |
| 741 | |
| 742 uint32_t TextBuffer::Utf8Decode( | |
| 743 const uint8_t* utf8_array, intptr_t array_len, uint32_t* dst) { | |
| 744 uint32_t ch = utf8_array[0] & 0xFF; | |
| 745 intptr_t i = 1; | |
| 746 if (ch >= 0x80) { | |
| 747 intptr_t num_trail_bytes = kTrailBytes[ch]; | |
| 748 bool is_malformed = false; | |
| 749 for (; i < num_trail_bytes; ++i) { | |
| 750 if (i < array_len) { | |
| 751 uint8_t code_unit = utf8_array[i]; | |
| 752 is_malformed |= !IsTrailByte(code_unit); | |
| 753 ch = (ch << 6) + code_unit; | |
| 754 } else { | |
| 755 *dst = -1; | |
| 756 return 0; | |
| 757 } | |
| 758 } | |
| 759 ch -= kMagicBits[num_trail_bytes]; | |
| 760 if (!((is_malformed == false) && | |
| 761 (i == num_trail_bytes) && | |
| 762 !IsOutOfRange(ch) && | |
| 763 !IsNonShortestForm(ch, i) && | |
| 764 !IsSurrogate(ch))) { | |
| 765 *dst = -1; | |
| 766 return 0; | |
| 767 } | |
| 768 } | |
| 769 *dst = ch; | |
| 770 return i; | |
| 771 } | |
| 772 | |
| 773 | |
| 661 } // namespace dart | 774 } // namespace dart |
| OLD | NEW |