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

Unified Diff: sdk/lib/io/path_impl.dart

Issue 11959011: Fix Path.relativeTo in special case where base is a substring of this. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Fixed another bug - added tests for it. 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « sdk/lib/_internal/dartdoc/lib/dartdoc.dart ('k') | tests/standalone/io/path_test.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: sdk/lib/io/path_impl.dart
diff --git a/sdk/lib/io/path_impl.dart b/sdk/lib/io/path_impl.dart
index b3c98572d8cc58ddccddd2aa5ce935319614d27d..2ea2fea9893e3bf0bc4ccde1a394be2046e8d2b6 100644
--- a/sdk/lib/io/path_impl.dart
+++ b/sdk/lib/io/path_impl.dart
@@ -45,64 +45,68 @@ class _Path implements Path {
String toString() => _path;
Path relativeTo(Path base) {
- // Throws exception if an unimplemented or impossible case is reached.
// Returns a path "relative" such that
// base.join(relative) == this.canonicalize.
- // Throws an exception if no such path exists, or the case is not
- // implemented yet.
+ // Throws exception if an impossible case is reached.
+ if (base.isAbsolute != isAbsolute ||
+ base.isWindowsShare != isWindowsShare) {
+ throw new ArgumentError(
+ "Invalid case of Path.relativeTo(base):\n"
+ " Path and base must both be relative, or both absolute.\n"
+ " Arguments: $_path.relativeTo($base)");
+ }
+
var basePath = base.toString();
- if (base.isAbsolute && _path.startsWith(basePath) &&
- base.isWindowsShare == isWindowsShare) {
+ if (_path.startsWith(basePath)) {
if (_path == basePath) return new Path('.');
- if (base.hasTrailingSeparator) {
- return new Path(_path.substring(basePath.length));
- }
- if (_path[basePath.length] == '/') {
- return new Path(_path.substring(basePath.length + 1));
- }
- } else if (base.isAbsolute == isAbsolute &&
- base.isWindowsShare == isWindowsShare) {
- List<String> baseSegments = base.canonicalize().segments();
- List<String> pathSegments = canonicalize().segments();
- if (baseSegments.length == 1 && baseSegments[0] == '.') {
- baseSegments = [];
- }
- if (pathSegments.length == 1 && pathSegments[0] == '.') {
- pathSegments = [];
- }
- int common = 0;
- int length = min(pathSegments.length, baseSegments.length);
- while (common < length && pathSegments[common] == baseSegments[common]) {
- common++;
+ // There must be a '/' at the end of the match, or immediately after.
+ int matchEnd = basePath.length;
+ if (_path[matchEnd - 1] == '/' || _path[matchEnd] == '/') {
+ // Drop any extra '/' characters at matchEnd
+ while (matchEnd < _path.length && _path[matchEnd] == '/') {
+ matchEnd++;
+ }
+ return new Path(_path.substring(matchEnd)).canonicalize();
}
- final segments = new List<String>();
+ }
- if (common < baseSegments.length && baseSegments[common] == '..') {
- throw new ArgumentError(
- "Invalid case of Path.relativeTo(base):\n"
- " Base path has more '..'s than path does."
- " Arguments: $_path.relativeTo($base)");
- }
- for (int i = common; i < baseSegments.length; i++) {
- segments.add('..');
- }
- for (int i = common; i < pathSegments.length; i++) {
- segments.add('${pathSegments[i]}');
- }
- if (segments.isEmpty) {
- segments.add('.');
- }
- if (hasTrailingSeparator) {
+ List<String> baseSegments = base.canonicalize().segments();
+ List<String> pathSegments = canonicalize().segments();
+ if (baseSegments.length == 1 && baseSegments[0] == '.') {
+ baseSegments = [];
+ }
+ if (pathSegments.length == 1 && pathSegments[0] == '.') {
+ pathSegments = [];
+ }
+ int common = 0;
+ int length = min(pathSegments.length, baseSegments.length);
+ while (common < length && pathSegments[common] == baseSegments[common]) {
+ common++;
+ }
+ final segments = new List<String>();
+
+ if (common < baseSegments.length && baseSegments[common] == '..') {
+ throw new ArgumentError(
+ "Invalid case of Path.relativeTo(base):\n"
+ " Base path has more '..'s than path does."
+ " Arguments: $_path.relativeTo($base)");
+ }
+ for (int i = common; i < baseSegments.length; i++) {
+ segments.add('..');
+ }
+ for (int i = common; i < pathSegments.length; i++) {
+ segments.add('${pathSegments[i]}');
+ }
+ if (segments.isEmpty) {
+ segments.add('.');
+ }
+ if (hasTrailingSeparator) {
segments.add('');
- }
- return new Path(Strings.join(segments, '/'));
}
- throw new ArgumentError(
- "Invalid case of Path.relativeTo(base):\n"
- " Path and base must both be relative, or both absolute.\n"
- " Arguments: $_path.relativeTo($base)");
+ return new Path(Strings.join(segments, '/'));
}
+
Path join(Path further) {
if (further.isAbsolute) {
throw new ArgumentError(
« no previous file with comments | « sdk/lib/_internal/dartdoc/lib/dartdoc.dart ('k') | tests/standalone/io/path_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698