diff --git a/docs/content/error/$location/badpath.ngdoc b/docs/content/error/$location/badpath.ngdoc new file mode 100644 index 000000000000..65c6f39dd2bb --- /dev/null +++ b/docs/content/error/$location/badpath.ngdoc @@ -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`. diff --git a/src/ng/location.js b/src/ng/location.js index 53a20cda62f0..3c4a284c121f 100644 --- a/src/ng/location.js +++ b/src/ng/location.js @@ -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 (DOUBLE_SLASH_REGEX.test(url)) { + throw $locationMinErr('badpath', 'Invalid url "{0}".', url); + } + + var prefixed = (url.charAt(0) !== '/'); if (prefixed) { - relativeUrl = '/' + relativeUrl; + url = '/' + url; } - var match = urlResolve(relativeUrl); + 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; diff --git a/test/ng/locationSpec.js b/test/ng/locationSpec.js index ae4a6674c062..c2715db0e599 100644 --- a/test/ng/locationSpec.js +++ b/test/ng/locationSpec.js @@ -389,7 +389,7 @@ describe('$location', function() { it('should throw error when invalid server url given', function() { - var locationUrl = new LocationHtml5Url('http://server.org/base/abc', 'http://server.org/base/', '/base'); + var locationUrl = new LocationHtml5Url('http://server.org/base/abc', 'http://server.org/base/'); expect(function() { locationUrl.$$parse('http://other.server.org/path#/path'); @@ -398,7 +398,7 @@ describe('$location', function() { it('should throw error when invalid base url given', function() { - var locationUrl = new LocationHtml5Url('http://server.org/base/abc', 'http://server.org/base/', '/base'); + var locationUrl = new LocationHtml5Url('http://server.org/base/abc', 'http://server.org/base/'); expect(function() { locationUrl.$$parse('http://server.org/path#/path'); @@ -2453,9 +2453,9 @@ describe('$location', function() { var locationUrl, locationUmlautUrl, locationIndexUrl; beforeEach(function() { - locationUrl = new LocationHtml5Url('http://server/pre/', 'http://server/pre/', 'http://server/pre/path'); - locationUmlautUrl = new LocationHtml5Url('http://särver/pre/', 'http://särver/pre/', 'http://särver/pre/path'); - locationIndexUrl = new LocationHtml5Url('http://server/pre/index.html', 'http://server/pre/', 'http://server/pre/path'); + locationUrl = new LocationHtml5Url('http://server/pre/', 'http://server/pre/'); + locationUmlautUrl = new LocationHtml5Url('http://särver/pre/', 'http://särver/pre/'); + locationIndexUrl = new LocationHtml5Url('http://server/pre/index.html', 'http://server/pre/'); }); it('should rewrite URL', function() { @@ -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) {