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

Side by Side Diff: runtime/vm/scanner.cc

Issue 10388179: Reject high- and low-surrogates in escaped code points. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: continue scanning after an invalid escaped code point Created 8 years, 7 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/vm/scanner.h ('k') | runtime/vm/scanner_test.cc » ('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 "vm/scanner.h" 5 #include "vm/scanner.h"
6 6
7 #include "platform/assert.h" 7 #include "platform/assert.h"
8 #include "vm/flags.h" 8 #include "vm/flags.h"
9 #include "vm/object.h" 9 #include "vm/object.h"
10 #include "vm/object_store.h" 10 #include "vm/object_store.h"
(...skipping 455 matching lines...) Expand 10 before | Expand all | Expand 10 after
466 break; 466 break;
467 } 467 }
468 *value <<= 4; 468 *value <<= 4;
469 *value |= Utils::HexDigitToInt(c0_); 469 *value |= Utils::HexDigitToInt(c0_);
470 ReadChar(); 470 ReadChar();
471 } 471 }
472 return true; 472 return true;
473 } 473 }
474 474
475 475
476 bool Scanner::ScanEscapedCodePoint(uint32_t* code_point) { 476 void Scanner::ScanEscapedCodePoint(uint32_t* code_point) {
477 ASSERT(c0_ == 'u' || c0_ == 'x'); 477 ASSERT(c0_ == 'u' || c0_ == 'x');
478 bool is_valid; 478 bool is_valid;
479 if (c0_ == 'x') { 479 if (c0_ == 'x') {
480 is_valid = ScanHexDigits(2, code_point); 480 is_valid = ScanHexDigits(2, code_point);
481 } else if (c0_ == 'u' && LookaheadChar(1) != '{') { 481 } else if (c0_ == 'u' && LookaheadChar(1) != '{') {
482 is_valid = ScanHexDigits(4, code_point); 482 is_valid = ScanHexDigits(4, code_point);
483 } else { 483 } else {
484 ReadChar(); // Skip left curly bracket. 484 ReadChar(); // Skip left curly bracket.
485 is_valid = ScanHexDigits(1, 6, code_point); 485 is_valid = ScanHexDigits(1, 6, code_point);
486 if (is_valid) { 486 if (is_valid) {
487 if (c0_ != '}') { 487 if (c0_ != '}') {
488 ErrorMsg("expected '}' after character code"); 488 ErrorMsg("expected '}' after character code");
489 return false; 489 return;
490 }
491 if (*code_point > 0x10FFFF) {
492 ErrorMsg("invalid code point");
493 return false;
494 } 490 }
495 } 491 }
496 } 492 }
497 return is_valid; 493 if (is_valid &&
494 ((*code_point > 0x10FFFF) ||
495 ((*code_point & 0xFFFFF800) == 0xD800))) {
496 ErrorMsg("invalid code point");
497 }
498 } 498 }
499 499
500 500
501 void Scanner::ScanLiteralStringChars(bool is_raw) { 501 void Scanner::ScanLiteralStringChars(bool is_raw) {
502 GrowableArray<uint32_t> string_chars(64); 502 GrowableArray<uint32_t> string_chars(64);
503 503
504 ASSERT(IsScanningString()); 504 ASSERT(IsScanningString());
505 // We are at the first character of a string literal piece. A string literal 505 // We are at the first character of a string literal piece. A string literal
506 // can be broken up into multiple pieces by string interpolation. 506 // can be broken up into multiple pieces by string interpolation.
507 while (true) { 507 while (true) {
(...skipping 19 matching lines...) Expand all
527 case 't': 527 case 't':
528 escape_char = '\t'; 528 escape_char = '\t';
529 break; 529 break;
530 case 'b': 530 case 'b':
531 escape_char = '\b'; 531 escape_char = '\b';
532 break; 532 break;
533 case 'v': 533 case 'v':
534 escape_char = '\v'; 534 escape_char = '\v';
535 break; 535 break;
536 case 'u': 536 case 'u':
537 case 'x': 537 case 'x': {
538 if (!ScanEscapedCodePoint(&escape_char)) { 538 ScanEscapedCodePoint(&escape_char);
539 EndStringLiteral();
540 return;
541 }
542 break; 539 break;
540 }
543 default: 541 default:
544 if ((c0_ == '\0') || ((c0_ == '\n') && !string_is_multiline_)) { 542 if ((c0_ == '\0') || ((c0_ == '\n') && !string_is_multiline_)) {
545 ErrorMsg("unterminated string literal"); 543 ErrorMsg("unterminated string literal");
546 EndStringLiteral(); 544 EndStringLiteral();
547 return; 545 return;
548 } 546 }
549 escape_char = c0_; 547 escape_char = c0_;
550 break; 548 break;
551 } 549 }
552 string_chars.Add(escape_char); 550 string_chars.Add(escape_char);
553 } else if (c0_ == '$' && !is_raw) { 551 } else if (c0_ == '$' && !is_raw) {
554 // Scanned a string piece. 552 // Scanned a string piece.
555 ASSERT(string_chars.data() != NULL); 553 ASSERT(string_chars.data() != NULL);
556 // Strings are canonicalized: Allocate a symbol. 554 // Strings are canonicalized: Allocate a symbol.
557 current_token_.literal = &String::ZoneHandle( 555 current_token_.literal = &String::ZoneHandle(
558 String::NewSymbol(string_chars.data(), string_chars.length())); 556 String::NewSymbol(string_chars.data(), string_chars.length()));
559 current_token_.kind = Token::kSTRING; 557 // Preserve error tokens.
558 if (current_token_.kind != Token::kERROR) {
559 current_token_.kind = Token::kSTRING;
560 }
560 return; 561 return;
561 } else if (c0_ == string_delimiter_) { 562 } else if (c0_ == string_delimiter_) {
562 // Check if we are at the end of the string literal. 563 // Check if we are at the end of the string literal.
563 if (!string_is_multiline_ || 564 if (!string_is_multiline_ ||
564 ((LookaheadChar(1) == string_delimiter_) && 565 ((LookaheadChar(1) == string_delimiter_) &&
565 (LookaheadChar(2) == string_delimiter_))) { 566 (LookaheadChar(2) == string_delimiter_))) {
566 if (string_is_multiline_) { 567 if (string_is_multiline_) {
567 ReadChar(); // Skip two string delimiters. 568 ReadChar(); // Skip two string delimiters.
568 ReadChar(); 569 ReadChar();
569 } 570 }
570 Recognize(Token::kSTRING); 571 // Preserve error tokens.
571 ASSERT(string_chars.data() != NULL); 572 if (current_token_.kind == Token::kERROR) {
572 // Strings are canonicalized: Allocate a symbol. 573 ReadChar();
573 current_token_.literal = &String::ZoneHandle( 574 } else {
574 String::NewSymbol(string_chars.data(), string_chars.length())); 575 Recognize(Token::kSTRING);
576 ASSERT(string_chars.data() != NULL);
577 // Strings are canonicalized: Allocate a symbol.
578 current_token_.literal = &String::ZoneHandle(
579 String::NewSymbol(string_chars.data(), string_chars.length()));
580 }
575 EndStringLiteral(); 581 EndStringLiteral();
576 return; 582 return;
577 } else { 583 } else {
578 string_chars.Add(string_delimiter_); 584 string_chars.Add(string_delimiter_);
579 } 585 }
580 } else { 586 } else {
581 string_chars.Add(c0_); 587 string_chars.Add(c0_);
582 } 588 }
583 ReadChar(); 589 ReadChar();
584 } 590 }
(...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after
914 "%c%"PRIxPTR, kPrivateKeySeparator, key_value); 920 "%c%"PRIxPTR, kPrivateKeySeparator, key_value);
915 const String& result = String::Handle(String::New(private_key)); 921 const String& result = String::Handle(String::New(private_key));
916 return result.raw(); 922 return result.raw();
917 } 923 }
918 924
919 925
920 void Scanner::InitOnce() { 926 void Scanner::InitOnce() {
921 } 927 }
922 928
923 } // namespace dart 929 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/scanner.h ('k') | runtime/vm/scanner_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698