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

Side by Side Diff: sdk/lib/core/uri.dart

Issue 389603002: Add extra information to FormatException. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Address comments. Created 6 years, 5 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 part of dart.core; 5 part of dart.core;
6 6
7 /** 7 /**
8 * A parsed URI, such as a URL. 8 * A parsed URI, such as a URL.
9 * 9 *
10 * **See also:** 10 * **See also:**
(...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after
389 userinfo, 389 userinfo,
390 host, 390 host,
391 port, 391 port,
392 path, 392 path,
393 query, 393 query,
394 fragment); 394 fragment);
395 } 395 }
396 396
397 // Report a parse failure. 397 // Report a parse failure.
398 static void _fail(String uri, int index, String message) { 398 static void _fail(String uri, int index, String message) {
399 // TODO(lrn): Consider adding this to FormatException. 399 throw new FormatException(message, uri, index);
400 if (index == uri.length) {
401 message += " at end of input.";
402 } else {
403 message += " at position $index.\n";
404 // Pick a slice of uri containing index and, if
405 // necessary, truncate the ends to ensure the entire
406 // slice fits on one line.
407 int min = 0;
408 int max = uri.length;
409 String pre = "";
410 String post = "";
411 if (uri.length > 78) {
412 min = index - 10;
413 if (min < 0) min = 0;
414 int max = min + 72;
415 if (max > uri.length) {
416 max = uri.length;
417 min = max - 72;
418 }
419 if (min != 0) pre = "...";
420 if (max != uri.length) post = "...";
421 }
422 // Combine message, slice and a caret pointing to the error index.
423 message = "$message$pre${uri.substring(min, max)}$post\n"
424 "${' ' * (pre.length + index - min)}^";
425 }
426 throw new FormatException(message);
427 } 400 }
428 401
429 /// Internal non-verifying constructor. Only call with validated arguments. 402 /// Internal non-verifying constructor. Only call with validated arguments.
430 Uri._internal(this.scheme, 403 Uri._internal(this.scheme,
431 this._userInfo, 404 this._userInfo,
432 this._host, 405 this._host,
433 this._port, 406 this._port,
434 this._path, 407 this._path,
435 this._query, 408 this._query,
436 this._fragment); 409 this._fragment);
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
601 } 574 }
602 } 575 }
603 var hostEnd = hostStart; 576 var hostEnd = hostStart;
604 if (hostStart < authority.length && 577 if (hostStart < authority.length &&
605 authority.codeUnitAt(hostStart) == _LEFT_BRACKET) { 578 authority.codeUnitAt(hostStart) == _LEFT_BRACKET) {
606 // IPv6 host. 579 // IPv6 host.
607 for (; hostEnd < authority.length; hostEnd++) { 580 for (; hostEnd < authority.length; hostEnd++) {
608 if (authority.codeUnitAt(hostEnd) == _RIGHT_BRACKET) break; 581 if (authority.codeUnitAt(hostEnd) == _RIGHT_BRACKET) break;
609 } 582 }
610 if (hostEnd == authority.length) { 583 if (hostEnd == authority.length) {
611 throw new FormatException("Invalid IPv6 host entry."); 584 throw new FormatException("Invalid IPv6 host entry.",
585 authority, hostStart);
612 } 586 }
613 parseIPv6Address(authority, hostStart + 1, hostEnd); 587 parseIPv6Address(authority, hostStart + 1, hostEnd);
614 hostEnd++; // Skip the closing bracket. 588 hostEnd++; // Skip the closing bracket.
615 if (hostEnd != authority.length && 589 if (hostEnd != authority.length &&
616 authority.codeUnitAt(hostEnd) != _COLON) { 590 authority.codeUnitAt(hostEnd) != _COLON) {
617 throw new FormatException("Invalid end of authority"); 591 throw new FormatException("Invalid end of authority",
592 authority, hostEnd);
618 } 593 }
619 } 594 }
620 // Split host and port. 595 // Split host and port.
621 bool hasPort = false; 596 bool hasPort = false;
622 for (; hostEnd < authority.length; hostEnd++) { 597 for (; hostEnd < authority.length; hostEnd++) {
623 if (authority.codeUnitAt(hostEnd) == _COLON) { 598 if (authority.codeUnitAt(hostEnd) == _COLON) {
624 var portString = authority.substring(hostEnd + 1); 599 var portString = authority.substring(hostEnd + 1);
625 // We allow the empty port - falling back to initial value. 600 // We allow the empty port - falling back to initial value.
626 if (portString.isNotEmpty) port = int.parse(portString); 601 if (portString.isNotEmpty) port = int.parse(portString);
627 break; 602 break;
(...skipping 1176 matching lines...) Expand 10 before | Expand all | Expand 10 after
1804 * * 2010:836B:4179::836B:4179 1779 * * 2010:836B:4179::836B:4179
1805 */ 1780 */
1806 static List<int> parseIPv6Address(String host, [int start = 0, int end]) { 1781 static List<int> parseIPv6Address(String host, [int start = 0, int end]) {
1807 if (end == null) end = host.length; 1782 if (end == null) end = host.length;
1808 // An IPv6 address consists of exactly 8 parts of 1-4 hex digits, seperated 1783 // An IPv6 address consists of exactly 8 parts of 1-4 hex digits, seperated
1809 // by `:`'s, with the following exceptions: 1784 // by `:`'s, with the following exceptions:
1810 // 1785 //
1811 // - One (and only one) wildcard (`::`) may be present, representing a fill 1786 // - One (and only one) wildcard (`::`) may be present, representing a fill
1812 // of 0's. The IPv6 `::` is thus 16 bytes of `0`. 1787 // of 0's. The IPv6 `::` is thus 16 bytes of `0`.
1813 // - The last two parts may be replaced by an IPv4 address. 1788 // - The last two parts may be replaced by an IPv4 address.
1814 void error(String msg) { 1789 void error(String msg, [position]) {
1815 throw new FormatException('Illegal IPv6 address, $msg'); 1790 throw new FormatException('Illegal IPv6 address, $msg', host, position);
1816 } 1791 }
1817 int parseHex(int start, int end) { 1792 int parseHex(int start, int end) {
1818 if (end - start > 4) { 1793 if (end - start > 4) {
1819 error('an IPv6 part can only contain a maximum of 4 hex digits'); 1794 error('an IPv6 part can only contain a maximum of 4 hex digits', start);
1820 } 1795 }
1821 int value = int.parse(host.substring(start, end), radix: 16); 1796 int value = int.parse(host.substring(start, end), radix: 16);
1822 if (value < 0 || value > (1 << 16) - 1) { 1797 if (value < 0 || value > (1 << 16) - 1) {
1823 error('each part must be in the range of `0x0..0xFFFF`'); 1798 error('each part must be in the range of `0x0..0xFFFF`', start);
1824 } 1799 }
1825 return value; 1800 return value;
1826 } 1801 }
1827 if (host.length < 2) error('address is too short'); 1802 if (host.length < 2) error('address is too short');
1828 List<int> parts = []; 1803 List<int> parts = [];
1829 bool wildcardSeen = false; 1804 bool wildcardSeen = false;
1830 int partStart = start; 1805 int partStart = start;
1831 // Parse all parts, except a potential last one. 1806 // Parse all parts, except a potential last one.
1832 for (int i = start; i < end; i++) { 1807 for (int i = start; i < end; i++) {
1833 if (host.codeUnitAt(i) == _COLON) { 1808 if (host.codeUnitAt(i) == _COLON) {
1834 if (i == start) { 1809 if (i == start) {
1835 // If we see a `:` in the beginning, expect wildcard. 1810 // If we see a `:` in the beginning, expect wildcard.
1836 i++; 1811 i++;
1837 if (host.codeUnitAt(i) != _COLON) { 1812 if (host.codeUnitAt(i) != _COLON) {
1838 error('invalid start colon.'); 1813 error('invalid start colon.', i);
1839 } 1814 }
1840 partStart = i; 1815 partStart = i;
1841 } 1816 }
1842 if (i == partStart) { 1817 if (i == partStart) {
1843 // Wildcard. We only allow one. 1818 // Wildcard. We only allow one.
1844 if (wildcardSeen) { 1819 if (wildcardSeen) {
1845 error('only one wildcard `::` is allowed'); 1820 error('only one wildcard `::` is allowed', i);
1846 } 1821 }
1847 wildcardSeen = true; 1822 wildcardSeen = true;
1848 parts.add(-1); 1823 parts.add(-1);
1849 } else { 1824 } else {
1850 // Found a single colon. Parse [partStart..i] as a hex entry. 1825 // Found a single colon. Parse [partStart..i] as a hex entry.
1851 parts.add(parseHex(partStart, i)); 1826 parts.add(parseHex(partStart, i));
1852 } 1827 }
1853 partStart = i + 1; 1828 partStart = i + 1;
1854 } 1829 }
1855 } 1830 }
1856 if (parts.length == 0) error('too few parts'); 1831 if (parts.length == 0) error('too few parts');
1857 bool atEnd = (partStart == end); 1832 bool atEnd = (partStart == end);
1858 bool isLastWildcard = (parts.last == -1); 1833 bool isLastWildcard = (parts.last == -1);
1859 if (atEnd && !isLastWildcard) { 1834 if (atEnd && !isLastWildcard) {
1860 error('expected a part after last `:`'); 1835 error('expected a part after last `:`', end);
1861 } 1836 }
1862 if (!atEnd) { 1837 if (!atEnd) {
1863 try { 1838 try {
1864 parts.add(parseHex(partStart, end)); 1839 parts.add(parseHex(partStart, end));
1865 } catch (e) { 1840 } catch (e) {
1866 // Failed to parse the last chunk as hex. Try IPv4. 1841 // Failed to parse the last chunk as hex. Try IPv4.
1867 try { 1842 try {
1868 List<int> last = parseIPv4Address(host.substring(partStart, end)); 1843 List<int> last = parseIPv4Address(host.substring(partStart, end));
1869 parts.add(last[0] << 8 | last[1]); 1844 parts.add(last[0] << 8 | last[1]);
1870 parts.add(last[2] << 8 | last[3]); 1845 parts.add(last[2] << 8 | last[3]);
1871 } catch (e) { 1846 } catch (e) {
1872 error('invalid end of IPv6 address.'); 1847 error('invalid end of IPv6 address.', partStart);
1873 } 1848 }
1874 } 1849 }
1875 } 1850 }
1876 if (wildcardSeen) { 1851 if (wildcardSeen) {
1877 if (parts.length > 7) { 1852 if (parts.length > 7) {
1878 error('an address with a wildcard must have less than 7 parts'); 1853 error('an address with a wildcard must have less than 7 parts');
1879 } 1854 }
1880 } else if (parts.length != 8) { 1855 } else if (parts.length != 8) {
1881 error('an address without a wildcard must contain exactly 8 parts'); 1856 error('an address without a wildcard must contain exactly 8 parts');
1882 } 1857 }
(...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after
2279 0xafff, // 0x30 - 0x3f 1111111111110101 2254 0xafff, // 0x30 - 0x3f 1111111111110101
2280 // @ABCDEFGHIJKLMNO 2255 // @ABCDEFGHIJKLMNO
2281 0xffff, // 0x40 - 0x4f 1111111111111111 2256 0xffff, // 0x40 - 0x4f 1111111111111111
2282 // PQRSTUVWXYZ _ 2257 // PQRSTUVWXYZ _
2283 0x87ff, // 0x50 - 0x5f 1111111111100001 2258 0x87ff, // 0x50 - 0x5f 1111111111100001
2284 // abcdefghijklmno 2259 // abcdefghijklmno
2285 0xfffe, // 0x60 - 0x6f 0111111111111111 2260 0xfffe, // 0x60 - 0x6f 0111111111111111
2286 // pqrstuvwxyz ~ 2261 // pqrstuvwxyz ~
2287 0x47ff]; // 0x70 - 0x7f 1111111111100010 2262 0x47ff]; // 0x70 - 0x7f 1111111111100010
2288 } 2263 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698