Index: sdk/lib/core/uri.dart |
diff --git a/sdk/lib/core/uri.dart b/sdk/lib/core/uri.dart |
index d7f911bfa55d98e782e3be82b6730191046c91b2..63f485d638d1a2bbcf25f73d68ef36079c7d8910 100644 |
--- a/sdk/lib/core/uri.dart |
+++ b/sdk/lib/core/uri.dart |
@@ -4323,10 +4323,6 @@ class _SimpleUri implements Uri { |
base._schemeCache); |
} |
// Merge paths. |
- if (base._uri.startsWith("../", base._pathStart)) { |
- // Complex rare case, go slow. |
- return _toNonSimple().resolveUri(ref); |
- } |
// The RFC 3986 algorithm merges the base path without its final segment |
// (anything after the final "/", or everything if the base path doesn't |
@@ -4341,9 +4337,10 @@ class _SimpleUri implements Uri { |
String refUri = ref._uri; |
int baseStart = base._pathStart; |
int baseEnd = base._queryStart; |
+ while (baseUri.startsWith("../", baseStart)) baseStart += 3; |
int refStart = ref._pathStart; |
int refEnd = ref._queryStart; |
- int backCount = 1; |
+ int backCount = 0; |
eernst
2016/09/29 12:28:49
It would help to document this variable. Is it som
Lasse Reichstein Nielsen
2016/09/29 12:58:30
Done.
|
int slashCount = 0; |
@@ -4363,17 +4360,27 @@ class _SimpleUri implements Uri { |
int char = baseUri.codeUnitAt(baseEnd); |
if (char == _SLASH) { |
insert = "/"; |
- backCount--; |
if (backCount == 0) break; |
+ backCount--; |
} |
} |
eernst
2016/09/29 12:28:49
This while loop seems to cut off segments starting
Lasse Reichstein Nielsen
2016/09/29 12:58:30
Done.
|
- // If the base URI has no scheme or authority (`_pathStart == 0`) |
- // and a relative path, and we reached the beginning of the path, |
- // we have a special case. |
- if (baseEnd == 0 && !base.hasAbsolutePath) { |
- // Non-RFC 3986 behavior when resolving a purely relative path on top of |
- // another relative path: Don't make the result absolute. |
- insert = ""; |
+ |
+ if (!base.hasScheme && !base.hasAbsolutePath) { |
+ // If the base is *just* a relative path (no scheme or authority), |
+ // then merging with another relative path doesn't follow the |
+ // RFC-3986 behavior. |
+ // Don't need to check `base.hasAuthority` since the base path is |
+ // non-empty - if there is an authority, a non-empty path is absolute. |
+ if (backCount > 0) { |
+ // We reached the start of the base path with more "../" left over |
+ // in the reference path. Include those in the result. |
+ refStart -= backCount * 3; |
+ insert = ""; |
+ } else if (baseEnd == baseStart) { |
+ // We reached the start of the base path with no more "../" left |
+ // over, so don't insert a "/" - that would make the result absolute. |
eernst
2016/09/29 12:28:49
Would be nice to have an explicit "this is the cas
Lasse Reichstein Nielsen
2016/09/29 12:58:30
That is what it says right above (look for RFC-398
|
+ insert = ""; |
+ } |
} |
var delta = baseEnd - refStart + insert.length; |