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

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

Issue 2374253004: Fix bug in _SimpleUri.resolve. (Closed)
Patch Set: Address comments. Created 4 years, 2 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
« no previous file with comments | « no previous file | tests/corelib/uri_test.dart » ('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 part of dart.core; 5 part of dart.core;
6 6
7 // Frequently used character codes. 7 // Frequently used character codes.
8 const int _SPACE = 0x20; 8 const int _SPACE = 0x20;
9 const int _PERCENT = 0x25; 9 const int _PERCENT = 0x25;
10 const int _PLUS = 0x2B; 10 const int _PLUS = 0x2B;
(...skipping 4305 matching lines...) Expand 10 before | Expand all | Expand 10 after
4316 return new _SimpleUri(newUri, 4316 return new _SimpleUri(newUri,
4317 base._schemeEnd, 4317 base._schemeEnd,
4318 base._hostStart, 4318 base._hostStart,
4319 base._portStart, 4319 base._portStart,
4320 base._pathStart, 4320 base._pathStart,
4321 ref._queryStart + delta, 4321 ref._queryStart + delta,
4322 ref._fragmentStart + delta, 4322 ref._fragmentStart + delta,
4323 base._schemeCache); 4323 base._schemeCache);
4324 } 4324 }
4325 // Merge paths. 4325 // Merge paths.
4326 if (base._uri.startsWith("../", base._pathStart)) {
4327 // Complex rare case, go slow.
4328 return _toNonSimple().resolveUri(ref);
4329 }
4330 4326
4331 // The RFC 3986 algorithm merges the base path without its final segment 4327 // The RFC 3986 algorithm merges the base path without its final segment
4332 // (anything after the final "/", or everything if the base path doesn't 4328 // (anything after the final "/", or everything if the base path doesn't
4333 // contain any "/"), and the reference path. 4329 // contain any "/"), and the reference path.
4334 // Then it removes "." and ".." segments using the remove-dot-segment 4330 // Then it removes "." and ".." segments using the remove-dot-segment
4335 // algorithm. 4331 // algorithm.
4336 // This code combines the two steps. It is simplified by knowing that 4332 // This code combines the two steps. It is simplified by knowing that
4337 // the base path contains no "." or ".." segments, and the reference 4333 // the base path contains no "." or ".." segments, and the reference
4338 // path can only contain leading ".." segments. 4334 // path can only contain leading ".." segments.
4339 4335
4340 String baseUri = base._uri; 4336 String baseUri = base._uri;
4341 String refUri = ref._uri; 4337 String refUri = ref._uri;
4342 int baseStart = base._pathStart; 4338 int baseStart = base._pathStart;
4343 int baseEnd = base._queryStart; 4339 int baseEnd = base._queryStart;
4340 while (baseUri.startsWith("../", baseStart)) baseStart += 3;
4344 int refStart = ref._pathStart; 4341 int refStart = ref._pathStart;
4345 int refEnd = ref._queryStart; 4342 int refEnd = ref._queryStart;
4346 int backCount = 1;
4347 4343
4348 int slashCount = 0; 4344 /// Count of leading ".." segments in reference path.
4349 4345 /// The count is decremented when the segment is matched with a
4350 // Count leading ".." segments in reference path. 4346 /// segment of the base path, and both are then omitted from the result.
4347 int backCount = 0;
4348 /// Count "../" segments and advance `refStart` to after the segments.
4351 while (refStart + 3 <= refEnd && refUri.startsWith("../", refStart)) { 4349 while (refStart + 3 <= refEnd && refUri.startsWith("../", refStart)) {
4352 refStart += 3; 4350 refStart += 3;
4353 backCount += 1; 4351 backCount += 1;
4354 } 4352 }
4355 4353
4356 // Extra slash inserted between base and reference path parts if 4354 // Extra slash inserted between base and reference path parts if
4357 // the base path contains any slashes. 4355 // the base path contains any slashes, or empty string if none.
4358 // (We could use a slash from the base path in most cases, but not if 4356 // (We could use a slash from the base path in most cases, but not if
4359 // we remove the entire base path). 4357 // we remove the entire base path).
4360 String insert = ""; 4358 String insert = "";
4359
4360 /// Remove segments from the base path.
4361 /// Start with the segment trailing the last slash,
4362 /// then remove segments for each leading "../" segment
4363 /// from the reference path, or as many of them as are available.
4361 while (baseEnd > baseStart) { 4364 while (baseEnd > baseStart) {
4362 baseEnd--; 4365 baseEnd--;
4363 int char = baseUri.codeUnitAt(baseEnd); 4366 int char = baseUri.codeUnitAt(baseEnd);
4364 if (char == _SLASH) { 4367 if (char == _SLASH) {
4365 insert = "/"; 4368 insert = "/";
4369 if (backCount == 0) break;
4366 backCount--; 4370 backCount--;
4367 if (backCount == 0) break;
4368 } 4371 }
4369 } 4372 }
4370 // If the base URI has no scheme or authority (`_pathStart == 0`) 4373
4371 // and a relative path, and we reached the beginning of the path, 4374 if (baseEnd == baseStart && !base.hasScheme && !base.hasAbsolutePath) {
4372 // we have a special case. 4375 // If the base is *just* a relative path (no scheme or authority),
4373 if (baseEnd == 0 && !base.hasAbsolutePath) { 4376 // then merging with another relative path doesn't follow the
4374 // Non-RFC 3986 behavior when resolving a purely relative path on top of 4377 // RFC-3986 behavior.
4375 // another relative path: Don't make the result absolute. 4378 // Don't need to check `base.hasAuthority` since the base path is
4379 // non-empty - if there is an authority, a non-empty path is absolute.
4380
4381 // We reached the start of the base path, and want to stay relative,
4382 // so don't insert a slash.
4376 insert = ""; 4383 insert = "";
4384 // If we reached the start of the base path with more "../" left over
4385 // in the reference path, include those segments in the result.
4386 refStart -= backCount * 3;
4377 } 4387 }
4378 4388
4379 var delta = baseEnd - refStart + insert.length; 4389 var delta = baseEnd - refStart + insert.length;
4380 var newUri = "${base._uri.substring(0, baseEnd)}$insert" 4390 var newUri = "${base._uri.substring(0, baseEnd)}$insert"
4381 "${ref._uri.substring(refStart)}"; 4391 "${ref._uri.substring(refStart)}";
4382 4392
4383 return new _SimpleUri(newUri, 4393 return new _SimpleUri(newUri,
4384 base._schemeEnd, 4394 base._schemeEnd,
4385 base._hostStart, 4395 base._hostStart,
4386 base._portStart, 4396 base._portStart,
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
4458 int delta = (text.codeUnitAt(start + 4) ^ _COLON) * 3; 4468 int delta = (text.codeUnitAt(start + 4) ^ _COLON) * 3;
4459 delta |= text.codeUnitAt(start) ^ 0x64 /*d*/; 4469 delta |= text.codeUnitAt(start) ^ 0x64 /*d*/;
4460 delta |= text.codeUnitAt(start + 1) ^ 0x61 /*a*/; 4470 delta |= text.codeUnitAt(start + 1) ^ 0x61 /*a*/;
4461 delta |= text.codeUnitAt(start + 2) ^ 0x74 /*t*/; 4471 delta |= text.codeUnitAt(start + 2) ^ 0x74 /*t*/;
4462 delta |= text.codeUnitAt(start + 3) ^ 0x61 /*a*/; 4472 delta |= text.codeUnitAt(start + 3) ^ 0x61 /*a*/;
4463 return delta; 4473 return delta;
4464 } 4474 }
4465 4475
4466 /// Helper function returning the length of a string, or `0` for `null`. 4476 /// Helper function returning the length of a string, or `0` for `null`.
4467 int _stringOrNullLength(String s) => (s == null) ? 0 : s.length; 4477 int _stringOrNullLength(String s) => (s == null) ? 0 : s.length;
OLDNEW
« no previous file with comments | « no previous file | tests/corelib/uri_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698