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

Unified Diff: sdk/lib/core/uri.dart

Issue 2626013004: Fix invalid URIs generated using Uri constructor with clever paths. (Closed)
Patch Set: Created 3 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 | « no previous file | tests/corelib/uri_test.dart » ('j') | tests/corelib/uri_test.dart » ('J')
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: sdk/lib/core/uri.dart
diff --git a/sdk/lib/core/uri.dart b/sdk/lib/core/uri.dart
index 847521ac48b1f52cf89d2a3a09bbbed59e54a671..fa7d01bee76617b64085856b948cf738d2539b55 100644
--- a/sdk/lib/core/uri.dart
+++ b/sdk/lib/core/uri.dart
@@ -1470,10 +1470,13 @@ class _Uri implements Uri {
path = _makePath(path, 0, _stringOrNullLength(path), pathSegments,
scheme, hasAuthority);
if (scheme.isEmpty && host == null && !path.startsWith('/')) {
- path = _normalizeRelativePath(path);
+ path = _normalizeRelativePath(path, scheme.isNotEmpty || host != null);
floitsch 2017/01/12 16:05:49 I generally assign boolean variables to locals fir
Lasse Reichstein Nielsen 2017/01/16 08:17:23 Done.
} else {
path = _removeDotSegments(path);
}
+ if (host == null && path.startsWith("//")) {
+ host = "";
+ }
return new _Uri._internal(scheme, userInfo, host, port,
path, query, fragment);
}
@@ -2058,7 +2061,7 @@ class _Uri implements Uri {
/// Otherwise it follows the RFC 3986 "remove dot segments" algorithm.
static String _normalizePath(String path, String scheme, bool hasAuthority) {
if (scheme.isEmpty && !hasAuthority && !path.startsWith('/')) {
- return _normalizeRelativePath(path);
+ return _normalizeRelativePath(path, scheme.isNotEmpty || hasAuthority);
}
return _removeDotSegments(path);
}
@@ -2354,15 +2357,21 @@ class _Uri implements Uri {
/// Removes all `.` segments and any non-leading `..` segments.
///
+ /// If the path starts with something that looks like a scheme,
+ /// and [allowScheme] is false, the colon is escaped.
+ ///
/// Removing the ".." from a "bar/foo/.." sequence results in "bar/"
/// (trailing "/"). If the entire path is removed (because it contains as
/// many ".." segments as real segments), the result is "./".
/// This is different from an empty string, which represents "no path",
/// when you resolve it against a base URI with a path with a non-empty
/// final segment.
- static String _normalizeRelativePath(String path) {
+ static String _normalizeRelativePath(String path, bool allowScheme) {
assert(!path.startsWith('/')); // Only get called for relative paths.
- if (!_mayContainDotSegments(path)) return path;
+ if (!_mayContainDotSegments(path)) {
+ if (!allowScheme) path = _escapeScheme(path);
+ return path;
+ }
assert(path.isNotEmpty); // An empty path would not have dot segments.
List<String> output = [];
bool appendSlash = false;
@@ -2385,9 +2394,27 @@ class _Uri implements Uri {
return "./";
}
if (appendSlash || output.last == '..') output.add("");
+ if (!allowScheme) output[0] = _escapeScheme(output[0]);
return output.join("/");
}
+ /// If [path] starts with a valid scheme, escape the percent.
+ static String _escapeScheme(String path) {
+ if (path.length >= 2 && _isAlphabeticCharacter(path.codeUnitAt(0))) {
+ for (int i = 1; i < path.length; i++) {
+ int char = path.codeUnitAt(i);
+ if (char == _COLON) {
+ return "${path.substring(0, i)}%3A${path.substring(i + 1)}";
+ }
+ if (char > 127 ||
+ ((_schemeTable[char >> 4] & (1 << (char & 0x0f))) == 0)) {
+ break;
+ }
+ }
+ }
+ return path;
+ }
+
Uri resolve(String reference) {
return resolveUri(Uri.parse(reference));
}
@@ -2459,7 +2486,8 @@ class _Uri implements Uri {
// If both base and reference are relative paths,
// allow the merged path to start with "..".
// The RFC only specifies the case where the base has a scheme.
- targetPath = _normalizeRelativePath(mergedPath);
+ targetPath = _normalizeRelativePath(mergedPath,
+ this.hasScheme || this.hasAuthority);
}
}
}
@@ -2596,7 +2624,7 @@ class _Uri implements Uri {
assert(_text == null);
StringBuffer sb = new StringBuffer();
if (scheme.isNotEmpty) sb..write(scheme)..write(":");
- if (hasAuthority || path.startsWith("//") || (scheme == "file")) {
+ if (hasAuthority || (scheme == "file")) {
// File URIS always have the authority, even if it is empty.
// The empty URI means "localhost".
sb.write("//");
« no previous file with comments | « no previous file | tests/corelib/uri_test.dart » ('j') | tests/corelib/uri_test.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698