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

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: 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
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 as
koda 2014/09/10 21:42:07 Finish this comment.
rmacnak 2014/09/10 21:49:59 Done.
592 switch (cp) { 554 void TextBuffer::EscapeAndAddCodeUnit(uint32_t codeunit) {
turnidge 2014/09/10 19:55:28 Can you take a look at json_test and see if it nee
rmacnak 2014/09/10 21:38:49 Added.
555 switch (codeunit) {
593 case '"': 556 case '"':
594 Printf("%s", "\\\""); 557 Printf("%s", "\\\"");
595 break; 558 break;
596 case '\\': 559 case '\\':
597 Printf("%s", "\\\\"); 560 Printf("%s", "\\\\");
598 break; 561 break;
599 case '/': 562 case '/':
600 Printf("%s", "\\/"); 563 Printf("%s", "\\/");
601 break; 564 break;
602 case '\b': 565 case '\b':
603 Printf("%s", "\\b"); 566 Printf("%s", "\\b");
604 break; 567 break;
605 case '\f': 568 case '\f':
606 Printf("%s", "\\f"); 569 Printf("%s", "\\f");
607 break; 570 break;
608 case '\n': 571 case '\n':
609 Printf("%s", "\\n"); 572 Printf("%s", "\\n");
610 break; 573 break;
611 case '\r': 574 case '\r':
612 Printf("%s", "\\r"); 575 Printf("%s", "\\r");
613 break; 576 break;
614 case '\t': 577 case '\t':
615 Printf("%s", "\\t"); 578 Printf("%s", "\\t");
616 break; 579 break;
617 default: 580 default:
618 if (cp < 0x20) { 581 if (codeunit < 0x20) {
619 // Encode character as \u00HH. 582 // Encode character as \u00HH.
620 uint32_t digit2 = (cp >> 4) & 0xf; 583 uint32_t digit2 = (codeunit >> 4) & 0xf;
621 uint32_t digit3 = (cp & 0xf); 584 uint32_t digit3 = (codeunit & 0xf);
622 Printf("\\u00%c%c", 585 Printf("\\u00%c%c",
623 digit2 > 9 ? 'A' + (digit2 - 10) : '0' + digit2, 586 digit2 > 9 ? 'A' + (digit2 - 10) : '0' + digit2,
624 digit3 > 9 ? 'A' + (digit3 - 10) : '0' + digit3); 587 digit3 > 9 ? 'A' + (digit3 - 10) : '0' + digit3);
625 } else { 588 } else if (codeunit > 127) {
626 AddUTF8(cp); 589 // Encode character as \uHHHH.
590 uint32_t digit1 = (codeunit >> 12) & 0xf;
591 uint32_t digit2 = (codeunit >> 8) & 0xf;
592 uint32_t digit3 = (codeunit >> 4) & 0xf;
593 uint32_t digit4 = (codeunit & 0xf);
594 Printf("\\u%c%c%c%c",
595 digit1 > 9 ? 'A' + (digit1 - 10) : '0' + digit1,
596 digit2 > 9 ? 'A' + (digit2 - 10) : '0' + digit2,
597 digit3 > 9 ? 'A' + (digit3 - 10) : '0' + digit3,
598 digit4 > 9 ? 'A' + (digit4 - 10) : '0' + digit4);
599 } else {
600 AddChar(codeunit);
627 } 601 }
628 } 602 }
629 } 603 }
630 604
631 605
632 void TextBuffer::AddString(const char* s) { 606 void TextBuffer::AddString(const char* s) {
633 Printf("%s", s); 607 Printf("%s", s);
634 } 608 }
635 609
636 610
637 void TextBuffer::AddEscapedString(const char* s) { 611 void TextBuffer::AddEscapedString(const char* s) {
638 intptr_t len = strlen(s); 612 intptr_t len = strlen(s);
639 for (int i = 0; i < len; i++) { 613 for (int i = 0; i < len; i++) {
640 AddEscapedChar(s[i]); 614 EscapeAndAddCodeUnit(s[i]);
641 } 615 }
642 } 616 }
643 617
644 618
645 void TextBuffer::EnsureCapacity(intptr_t len) { 619 void TextBuffer::EnsureCapacity(intptr_t len) {
646 intptr_t remaining = buf_size_ - msg_len_; 620 intptr_t remaining = buf_size_ - msg_len_;
647 if (remaining <= len) { 621 if (remaining <= len) {
648 const int kBufferSpareCapacity = 64; // Somewhat arbitrary. 622 const int kBufferSpareCapacity = 64; // Somewhat arbitrary.
649 // TODO(turnidge): do we need to guard against overflow or other 623 // TODO(turnidge): do we need to guard against overflow or other
650 // security issues here? Text buffers are used by the debugger 624 // security issues here? Text buffers are used by the debugger
651 // to send user-controlled data (e.g. values of string variables) to 625 // to send user-controlled data (e.g. values of string variables) to
652 // the debugger front-end. 626 // the debugger front-end.
653 intptr_t new_size = buf_size_ + len + kBufferSpareCapacity; 627 intptr_t new_size = buf_size_ + len + kBufferSpareCapacity;
654 char* new_buf = reinterpret_cast<char*>(realloc(buf_, new_size)); 628 char* new_buf = reinterpret_cast<char*>(realloc(buf_, new_size));
655 ASSERT(new_buf != NULL); 629 ASSERT(new_buf != NULL);
656 buf_ = new_buf; 630 buf_ = new_buf;
657 buf_size_ = new_size; 631 buf_size_ = new_size;
658 } 632 }
659 } 633 }
660 634
661 } // namespace dart 635 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698