Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(192)

Side by Side Diff: runtime/platform/json.cc

Issue 558853004: Preserve the contents of Dart strings with unmatched surrogate halfs by avoiding a UTF16 -> UTF8 (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: sync and build Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/platform/json.h ('k') | runtime/tests/vm/vm.status » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 509 matching lines...) Expand 10 before | Expand all | Expand 10 after
520 520
521 521
522 void TextBuffer::AddChar(char ch) { 522 void TextBuffer::AddChar(char ch) {
523 EnsureCapacity(sizeof(ch)); 523 EnsureCapacity(sizeof(ch));
524 buf_[msg_len_] = ch; 524 buf_[msg_len_] = ch;
525 msg_len_++; 525 msg_len_++;
526 buf_[msg_len_] = '\0'; 526 buf_[msg_len_] = '\0';
527 } 527 }
528 528
529 529
530 void TextBuffer::AddUTF8(uint32_t ch) {
531 static const uint32_t kMaxOneByteChar = 0x7F;
532 static const uint32_t kMaxTwoByteChar = 0x7FF;
533 static const uint32_t kMaxThreeByteChar = 0xFFFF;
534 static const uint32_t kMaxFourByteChar = 0x10FFFF;
535 static const uint32_t kMask = ~(1 << 6);
536
537 if (ch <= kMaxOneByteChar) {
538 EnsureCapacity(1);
539 buf_[msg_len_++] = ch;
540 buf_[msg_len_] = '\0';
541 return;
542 }
543 if (ch <= kMaxTwoByteChar) {
544 EnsureCapacity(2);
545 buf_[msg_len_++] = 0xC0 | (ch >> 6);
546 buf_[msg_len_++] = 0x80 | (ch & kMask);
547 buf_[msg_len_] = '\0';
548 return;
549 }
550 if (ch <= kMaxThreeByteChar) {
551 EnsureCapacity(3);
552 buf_[msg_len_++] = 0xE0 | (ch >> 12);
553 buf_[msg_len_++] = 0x80 | ((ch >> 6) & kMask);
554 buf_[msg_len_++] = 0x80 | (ch & kMask);
555 buf_[msg_len_] = '\0';
556 return;
557 }
558 ASSERT(ch <= kMaxFourByteChar);
559 EnsureCapacity(4);
560 buf_[msg_len_++] = 0xF0 | (ch >> 18);
561 buf_[msg_len_++] = 0x80 | ((ch >> 12) & kMask);
562 buf_[msg_len_++] = 0x80 | ((ch >> 6) & kMask);
563 buf_[msg_len_++] = 0x80 | (ch & kMask);
564 buf_[msg_len_] = '\0';
565 }
566
567
568 intptr_t TextBuffer::Printf(const char* format, ...) { 530 intptr_t TextBuffer::Printf(const char* format, ...) {
569 va_list args; 531 va_list args;
570 va_start(args, format); 532 va_start(args, format);
571 intptr_t remaining = buf_size_ - msg_len_; 533 intptr_t remaining = buf_size_ - msg_len_;
572 ASSERT(remaining >= 0); 534 ASSERT(remaining >= 0);
573 intptr_t len = OS::VSNPrint(buf_ + msg_len_, remaining, format, args); 535 intptr_t len = OS::VSNPrint(buf_ + msg_len_, remaining, format, args);
574 va_end(args); 536 va_end(args);
575 if (len >= remaining) { 537 if (len >= remaining) {
576 EnsureCapacity(len); 538 EnsureCapacity(len);
577 remaining = buf_size_ - msg_len_; 539 remaining = buf_size_ - msg_len_;
578 ASSERT(remaining > len); 540 ASSERT(remaining > len);
579 va_list args2; 541 va_list args2;
580 va_start(args2, format); 542 va_start(args2, format);
581 intptr_t len2 = OS::VSNPrint(buf_ + msg_len_, remaining, format, args2); 543 intptr_t len2 = OS::VSNPrint(buf_ + msg_len_, remaining, format, args2);
582 va_end(args2); 544 va_end(args2);
583 ASSERT(len == len2); 545 ASSERT(len == len2);
584 } 546 }
585 msg_len_ += len; 547 msg_len_ += len;
586 buf_[msg_len_] = '\0'; 548 buf_[msg_len_] = '\0';
587 return len; 549 return len;
588 } 550 }
589 551
590 552
591 void TextBuffer::AddEscapedChar(uint32_t cp) { 553 // Write a UTF-16 code unit so it can be read by a JSON parser in a string
592 switch (cp) { 554 // literal. Use escape sequences for characters other than printable ASCII.
555 void TextBuffer::EscapeAndAddCodeUnit(uint32_t codeunit) {
556 switch (codeunit) {
593 case '"': 557 case '"':
594 Printf("%s", "\\\""); 558 Printf("%s", "\\\"");
595 break; 559 break;
596 case '\\': 560 case '\\':
597 Printf("%s", "\\\\"); 561 Printf("%s", "\\\\");
598 break; 562 break;
599 case '/': 563 case '/':
600 Printf("%s", "\\/"); 564 Printf("%s", "\\/");
601 break; 565 break;
602 case '\b': 566 case '\b':
603 Printf("%s", "\\b"); 567 Printf("%s", "\\b");
604 break; 568 break;
605 case '\f': 569 case '\f':
606 Printf("%s", "\\f"); 570 Printf("%s", "\\f");
607 break; 571 break;
608 case '\n': 572 case '\n':
609 Printf("%s", "\\n"); 573 Printf("%s", "\\n");
610 break; 574 break;
611 case '\r': 575 case '\r':
612 Printf("%s", "\\r"); 576 Printf("%s", "\\r");
613 break; 577 break;
614 case '\t': 578 case '\t':
615 Printf("%s", "\\t"); 579 Printf("%s", "\\t");
616 break; 580 break;
617 default: 581 default:
618 if (cp < 0x20) { 582 if (codeunit < 0x20) {
619 // Encode character as \u00HH. 583 // Encode character as \u00HH.
620 uint32_t digit2 = (cp >> 4) & 0xf; 584 uint32_t digit2 = (codeunit >> 4) & 0xf;
621 uint32_t digit3 = (cp & 0xf); 585 uint32_t digit3 = (codeunit & 0xf);
622 Printf("\\u00%c%c", 586 Printf("\\u00%c%c",
623 digit2 > 9 ? 'A' + (digit2 - 10) : '0' + digit2, 587 digit2 > 9 ? 'A' + (digit2 - 10) : '0' + digit2,
624 digit3 > 9 ? 'A' + (digit3 - 10) : '0' + digit3); 588 digit3 > 9 ? 'A' + (digit3 - 10) : '0' + digit3);
589 } else if (codeunit > 127) {
590 // Encode character as \uHHHH.
591 uint32_t digit0 = (codeunit >> 12) & 0xf;
592 uint32_t digit1 = (codeunit >> 8) & 0xf;
593 uint32_t digit2 = (codeunit >> 4) & 0xf;
594 uint32_t digit3 = (codeunit & 0xf);
595 Printf("\\u%c%c%c%c",
596 digit0 > 9 ? 'A' + (digit0 - 10) : '0' + digit0,
597 digit1 > 9 ? 'A' + (digit1 - 10) : '0' + digit1,
598 digit2 > 9 ? 'A' + (digit2 - 10) : '0' + digit2,
599 digit3 > 9 ? 'A' + (digit3 - 10) : '0' + digit3);
625 } else { 600 } else {
626 AddUTF8(cp); 601 AddChar(codeunit);
627 } 602 }
628 } 603 }
629 } 604 }
630 605
631 606
632 void TextBuffer::AddString(const char* s) { 607 void TextBuffer::AddString(const char* s) {
633 Printf("%s", s); 608 Printf("%s", s);
634 } 609 }
635 610
636 611
637 void TextBuffer::AddEscapedString(const char* s) { 612 void TextBuffer::AddEscapedString(const char* s) {
638 intptr_t len = strlen(s); 613 intptr_t len = strlen(s);
639 for (int i = 0; i < len; i++) { 614 for (int i = 0; i < len; i++) {
640 AddEscapedChar(s[i]); 615 EscapeAndAddCodeUnit(s[i]);
641 } 616 }
642 } 617 }
643 618
644 619
645 void TextBuffer::EnsureCapacity(intptr_t len) { 620 void TextBuffer::EnsureCapacity(intptr_t len) {
646 intptr_t remaining = buf_size_ - msg_len_; 621 intptr_t remaining = buf_size_ - msg_len_;
647 if (remaining <= len) { 622 if (remaining <= len) {
648 const int kBufferSpareCapacity = 64; // Somewhat arbitrary. 623 const int kBufferSpareCapacity = 64; // Somewhat arbitrary.
649 // TODO(turnidge): do we need to guard against overflow or other 624 // TODO(turnidge): do we need to guard against overflow or other
650 // security issues here? Text buffers are used by the debugger 625 // security issues here? Text buffers are used by the debugger
651 // to send user-controlled data (e.g. values of string variables) to 626 // to send user-controlled data (e.g. values of string variables) to
652 // the debugger front-end. 627 // the debugger front-end.
653 intptr_t new_size = buf_size_ + len + kBufferSpareCapacity; 628 intptr_t new_size = buf_size_ + len + kBufferSpareCapacity;
654 char* new_buf = reinterpret_cast<char*>(realloc(buf_, new_size)); 629 char* new_buf = reinterpret_cast<char*>(realloc(buf_, new_size));
655 ASSERT(new_buf != NULL); 630 ASSERT(new_buf != NULL);
656 buf_ = new_buf; 631 buf_ = new_buf;
657 buf_size_ = new_size; 632 buf_size_ = new_size;
658 } 633 }
659 } 634 }
660 635
661 } // namespace dart 636 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/platform/json.h ('k') | runtime/tests/vm/vm.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698