fix($location): throw if the path starts with double (back)slashes

Previously `$location` was rewriting such paths to remove not only the
double slashes but also the first segment of the path, leading to an invalid
path.

In this change, we deem leading double (back)slashes an invalid path and
now throw a `$location:badpath` error if that occurs.

Closes #15365
This commit is contained in:
Peter Bacon Darwin
2016-11-05 11:30:23 +00:00
parent 627459b96d
commit 4aa9534b0f
3 changed files with 34 additions and 6 deletions
@@ -0,0 +1,9 @@
@ngdoc error
@name $location:badpath
@fullName Invalid Path
@description
This error occurs when the path of a location contains invalid characters.
The most common fault is when the path starts with double slashes (`//`) or backslashes ('\\').
For example if the base path of an application is `https://a.b.c/` then the following path is
invalid `https://a.b.c///d/e/f`.
+12 -6
View File
@@ -30,13 +30,18 @@ function parseAbsoluteUrl(absoluteUrl, locationObj) {
locationObj.$$port = toInt(parsedUrl.port) || DEFAULT_PORTS[parsedUrl.protocol] || null;
}
var DOUBLE_SLASH_REGEX = /^\s*[\\/]{2,}/;
function parseAppUrl(url, locationObj) {
function parseAppUrl(relativeUrl, locationObj) {
var prefixed = (relativeUrl.charAt(0) !== '/');
if (prefixed) {
relativeUrl = '/' + relativeUrl;
if (DOUBLE_SLASH_REGEX.test(url)) {
throw $locationMinErr('badpath', 'Invalid url "{0}".', url);
}
var match = urlResolve(relativeUrl);
var prefixed = (url.charAt(0) !== '/');
if (prefixed) {
url = '/' + url;
}
var match = urlResolve(url);
locationObj.$$path = decodeURIComponent(prefixed && match.pathname.charAt(0) === '/' ?
match.pathname.substring(1) : match.pathname);
locationObj.$$search = parseKeyValue(match.search);
@@ -144,9 +149,10 @@ function LocationHtml5Url(appBase, appBaseNoFile, basePrefix) {
var appUrl, prevAppUrl;
var rewrittenUrl;
if (isDefined(appUrl = stripBaseUrl(appBase, url))) {
prevAppUrl = appUrl;
if (isDefined(appUrl = stripBaseUrl(basePrefix, appUrl))) {
if (basePrefix && isDefined(appUrl = stripBaseUrl(basePrefix, appUrl))) {
rewrittenUrl = appBaseNoFile + (stripBaseUrl('/', appUrl) || appUrl);
} else {
rewrittenUrl = appBase + prevAppUrl;
+13
View File
@@ -2480,6 +2480,19 @@ describe('$location', function() {
expect(parseLinkAndReturn(locationUrl, 'someIgnoredAbsoluteHref', '#test')).toEqual('http://server/pre/otherPath#test');
});
it('should complain if the path starts with double slashes', function() {
expect(function() {
parseLinkAndReturn(locationUrl, 'http://server/pre///other/path');
}).toThrowMinErr('$location', 'badpath');
expect(function() {
parseLinkAndReturn(locationUrl, 'http://server/pre/\\\\other/path');
}).toThrowMinErr('$location', 'badpath');
expect(function() {
parseLinkAndReturn(locationUrl, 'http://server/pre//\\//other/path');
}).toThrowMinErr('$location', 'badpath');
});
it('should complain if no base tag present', function() {
module(function($locationProvider) {