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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/string_validator.dart

Issue 11783009: Big merge from experimental to bleeding edge. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 11 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 // Check the validity of string literals. 5 // Check the validity of string literals.
6 6
7 library stringvalidator; 7 library stringvalidator;
8 8
9 import "dart2jslib.dart"; 9 import "dart2jslib.dart";
10 import "tree/tree.dart"; 10 import "tree/tree.dart";
(...skipping 27 matching lines...) Expand all
38 if (isFirst) leftQuote = quoting.leftQuoteLength; 38 if (isFirst) leftQuote = quoting.leftQuoteLength;
39 if (isLast) rightQuote = quoting.rightQuoteLength; 39 if (isLast) rightQuote = quoting.rightQuoteLength;
40 SourceString content = source.copyWithoutQuotes(leftQuote, rightQuote); 40 SourceString content = source.copyWithoutQuotes(leftQuote, rightQuote);
41 return validateString(token, 41 return validateString(token,
42 token.charOffset + leftQuote, 42 token.charOffset + leftQuote,
43 content, 43 content,
44 quoting); 44 quoting);
45 } 45 }
46 46
47 static StringQuoting quotingFromString(SourceString sourceString) { 47 static StringQuoting quotingFromString(SourceString sourceString) {
48 Iterator<int> source = sourceString.iterator(); 48 Iterator<int> source = sourceString.iterator;
49 bool raw = false; 49 bool raw = false;
50 int quoteLength = 1; 50 int quoteLength = 1;
51 int quoteChar = source.next(); 51 source.moveNext();
52 if (identical(quoteChar, $r)) { 52 int quoteChar = source.current;
53 if (quoteChar == $r) {
53 raw = true; 54 raw = true;
54 quoteChar = source.next(); 55 source.moveNext();
56 quoteChar = source.current;
55 } 57 }
56 assert(quoteChar == $SQ || quoteChar == $DQ); 58 assert(quoteChar == $SQ || quoteChar == $DQ);
57 // String has at least one quote. Check it if has three. 59 // String has at least one quote. Check it if has three.
58 // If it only have two, the string must be an empty string literal, 60 // If it only have two, the string must be an empty string literal,
59 // and end after the second quote. 61 // and end after the second quote.
60 bool multiline = false; 62 bool multiline = false;
61 if (source.hasNext && source.next() == quoteChar && source.hasNext) { 63 if (source.moveNext() && source.current == quoteChar && source.moveNext()) {
62 int code = source.next(); 64 int code = source.current;
63 assert(code == quoteChar); // If not, there is a bug in the parser. 65 assert(code == quoteChar); // If not, there is a bug in the parser.
64 quoteLength = 3; 66 quoteLength = 3;
65 // Check if a multiline string starts with a newline (CR, LF or CR+LF). 67 // Check if a multiline string starts with a newline (CR, LF or CR+LF).
66 if (source.hasNext) { 68 if (source.moveNext()) {
67 code = source.next(); 69 code = source.current;
68 if (code == $CR) { 70 if (code == $CR) {
69 quoteLength += 1; 71 quoteLength += 1;
70 if (source.hasNext && source.next() == $LF) { 72 if (source.moveNext() && source.current == $LF) {
71 quoteLength += 1; 73 quoteLength += 1;
72 } 74 }
73 } else if (code == $LF) { 75 } else if (code == $LF) {
74 quoteLength += 1; 76 quoteLength += 1;
75 } 77 }
76 } 78 }
77 } 79 }
78 return StringQuoting.getQuoting(quoteChar, raw, quoteLength); 80 return StringQuoting.getQuoting(quoteChar, raw, quoteLength);
79 } 81 }
80 82
(...skipping 11 matching lines...) Expand all
92 StringQuoting quoting) { 94 StringQuoting quoting) {
93 // We need to check for invalid x and u escapes, for line 95 // We need to check for invalid x and u escapes, for line
94 // terminators in non-multiline strings, and for invalid Unicode 96 // terminators in non-multiline strings, and for invalid Unicode
95 // scalar values (either directly or as u-escape values). We also check 97 // scalar values (either directly or as u-escape values). We also check
96 // for unpaired UTF-16 surrogates. 98 // for unpaired UTF-16 surrogates.
97 int length = 0; 99 int length = 0;
98 int index = startOffset; 100 int index = startOffset;
99 bool containsEscape = false; 101 bool containsEscape = false;
100 bool previousWasLeadSurrogate = false; 102 bool previousWasLeadSurrogate = false;
101 bool invalidUtf16 = false; 103 bool invalidUtf16 = false;
102 for(Iterator<int> iter = string.iterator(); iter.hasNext; length++) { 104 for(HasNextIterator<int> iter = new HasNextIterator(string.iterator);
105 iter.hasNext;
106 length++) {
103 index++; 107 index++;
104 int code = iter.next(); 108 int code = iter.next();
105 if (code == $BACKSLASH) { 109 if (code == $BACKSLASH) {
106 if (quoting.raw) continue; 110 if (quoting.raw) continue;
107 containsEscape = true; 111 containsEscape = true;
108 if (!iter.hasNext) { 112 if (!iter.hasNext) {
109 stringParseError("Incomplete escape sequence",token, index); 113 stringParseError("Incomplete escape sequence",token, index);
110 return null; 114 return null;
111 } 115 }
112 index++; 116 index++;
(...skipping 10 matching lines...) Expand all
123 stringParseError("Invalid character in escape sequence", 127 stringParseError("Invalid character in escape sequence",
124 token, index); 128 token, index);
125 return null; 129 return null;
126 } 130 }
127 } 131 }
128 // A two-byte hex escape can't generate an invalid value. 132 // A two-byte hex escape can't generate an invalid value.
129 continue; 133 continue;
130 } else if (code == $u) { 134 } else if (code == $u) {
131 int escapeStart = index - 1; 135 int escapeStart = index - 1;
132 index++; 136 index++;
133 code = iter.next(); 137 code = iter.hasNext ? iter.next() : 0;
134 int value = 0; 138 int value = 0;
135 if (code == $OPEN_CURLY_BRACKET) { 139 if (code == $OPEN_CURLY_BRACKET) {
136 // expect 1-6 hex digits. 140 // expect 1-6 hex digits.
137 int count = 0; 141 int count = 0;
138 index++; 142 while (iter.hasNext) {
139 code = iter.next(); 143 code = iter.next();
140 do { 144 index++;
145 if (code == $CLOSE_CURLY_BRACKET) {
146 break;
147 }
141 if (!isHexDigit(code)) { 148 if (!isHexDigit(code)) {
142 stringParseError("Invalid character in escape sequence", 149 stringParseError("Invalid character in escape sequence",
143 token, index); 150 token, index);
144 return null; 151 return null;
145 } 152 }
146 count++; 153 count++;
147 value = value * 16 + hexDigitValue(code); 154 value = value * 16 + hexDigitValue(code);
148 index++; 155 }
149 code = iter.next(); 156 if (code != $CLOSE_CURLY_BRACKET || count == 0 || count > 6) {
150 } while (code != $CLOSE_CURLY_BRACKET); 157 int errorPosition = index - count;
151 if (count > 6) { 158 if (count > 6) errorPosition += 6;
152 stringParseError("Invalid character in escape sequence", 159 stringParseError("Invalid character in escape sequence",
153 token, index - (count - 6)); 160 token, errorPosition);
154 return null; 161 return null;
155 } 162 }
156 } else { 163 } else {
157 // Expect four hex digits, including the one just read. 164 // Expect four hex digits, including the one just read.
158 for (int i = 0; i < 4; i++) { 165 for (int i = 0; i < 4; i++) {
159 if (i > 0) { 166 if (i > 0) {
160 index++; 167 if (iter.hasNext) {
161 code = iter.next(); 168 index++;
169 code = iter.next();
170 } else {
171 code = 0;
172 }
162 } 173 }
163 if (!isHexDigit(code)) { 174 if (!isHexDigit(code)) {
164 stringParseError("Invalid character in escape sequence", 175 stringParseError("Invalid character in escape sequence",
165 token, index); 176 token, index);
166 return null; 177 return null;
167 } 178 }
168 value = value * 16 + hexDigitValue(code); 179 value = value * 16 + hexDigitValue(code);
169 } 180 }
170 } 181 }
171 code = value; 182 code = value;
(...skipping 20 matching lines...) Expand all
192 return null; 203 return null;
193 } 204 }
194 // String literal successfully validated. 205 // String literal successfully validated.
195 if (quoting.raw || !containsEscape) { 206 if (quoting.raw || !containsEscape) {
196 // A string without escapes could just as well have been raw. 207 // A string without escapes could just as well have been raw.
197 return new DartString.rawString(string, length); 208 return new DartString.rawString(string, length);
198 } 209 }
199 return new DartString.escapedString(string, length); 210 return new DartString.escapedString(string, length);
200 } 211 }
201 } 212 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698