From cf5ddc8942425fea6594e90565e9281767c8ab7c Mon Sep 17 00:00:00 2001 From: Peter Bacon Darwin Date: Thu, 3 Nov 2016 14:10:53 +0000 Subject: [PATCH] fix($location): don't remove multiple slashes from urls --- src/ng/location.js | 25 +++++++++++++++---------- test/ng/locationSpec.js | 10 +++++++--- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/src/ng/location.js b/src/ng/location.js index 53a20cda62f0..74b201ee85f1 100644 --- a/src/ng/location.js +++ b/src/ng/location.js @@ -30,20 +30,25 @@ function parseAbsoluteUrl(absoluteUrl, locationObj) { locationObj.$$port = toInt(parsedUrl.port) || DEFAULT_PORTS[parsedUrl.protocol] || null; } +function countLeadingSlashes(url) { + for (var i = 0; url.charAt(i) === '/'; i++) { /* noop */} + return i; +} -function parseAppUrl(relativeUrl, locationObj) { - var prefixed = (relativeUrl.charAt(0) !== '/'); - if (prefixed) { - relativeUrl = '/' + relativeUrl; - } - var match = urlResolve(relativeUrl); - locationObj.$$path = decodeURIComponent(prefixed && match.pathname.charAt(0) === '/' ? - match.pathname.substring(1) : match.pathname); +function parseAppUrl(url, locationObj) { + var slashCount = countLeadingSlashes(url); + var slashes = url.substr(0, slashCount); + + // We need to pass a url with a single leading slash to the `urlResolve` function + // so we strip off all the slashes and put just one special one back on + var match = urlResolve('/' + url.substr(slashCount)); + // Then we put the slashes back on (removing the special one) + locationObj.$$path = decodeURIComponent(slashes + match.pathname.substr(1)); locationObj.$$search = parseKeyValue(match.search); locationObj.$$hash = decodeURIComponent(match.hash); - // make sure path starts with '/'; - if (locationObj.$$path && locationObj.$$path.charAt(0) !== '/') { + // fix up if we were passed a url with none or multiple leading slashes + if (locationObj.$$path && slashCount !== 1) { locationObj.$$path = '/' + locationObj.$$path; } } diff --git a/test/ng/locationSpec.js b/test/ng/locationSpec.js index ae4a6674c062..2b36f64b0ca1 100644 --- a/test/ng/locationSpec.js +++ b/test/ng/locationSpec.js @@ -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,10 @@ describe('$location', function() { expect(parseLinkAndReturn(locationUrl, 'someIgnoredAbsoluteHref', '#test')).toEqual('http://server/pre/otherPath#test'); }); + it('should cope with double slashes in the path', function() { + expect(parseLinkAndReturn(locationUrl, 'http://server/pre///other/path')).toEqual('http://server/pre///other/path'); + }); + it('should complain if no base tag present', function() { module(function($locationProvider) {