fix($location): do not decode forward slashes in the path in HTML5 mode
Closes #16312
This commit is contained in:
committed by
Pete Bacon Darwin
parent
667db466f9
commit
0cbc505121
+23
-7
@@ -16,7 +16,23 @@ function encodePath(path) {
|
||||
i = segments.length;
|
||||
|
||||
while (i--) {
|
||||
segments[i] = encodeUriSegment(segments[i]);
|
||||
// decode forward slashes to prevent them from being double encoded
|
||||
segments[i] = encodeUriSegment(segments[i].replace(/%2F/g, '/'));
|
||||
}
|
||||
|
||||
return segments.join('/');
|
||||
}
|
||||
|
||||
function decodePath(path, html5Mode) {
|
||||
var segments = path.split('/'),
|
||||
i = segments.length;
|
||||
|
||||
while (i--) {
|
||||
segments[i] = decodeURIComponent(segments[i]);
|
||||
if (html5Mode) {
|
||||
// encode forward slashes to prevent them from being mistaken for path separators
|
||||
segments[i] = segments[i].replace(/\//g, '%2F');
|
||||
}
|
||||
}
|
||||
|
||||
return segments.join('/');
|
||||
@@ -31,7 +47,7 @@ function parseAbsoluteUrl(absoluteUrl, locationObj) {
|
||||
}
|
||||
|
||||
var DOUBLE_SLASH_REGEX = /^\s*[\\/]{2,}/;
|
||||
function parseAppUrl(url, locationObj) {
|
||||
function parseAppUrl(url, locationObj, html5Mode) {
|
||||
|
||||
if (DOUBLE_SLASH_REGEX.test(url)) {
|
||||
throw $locationMinErr('badpath', 'Invalid url "{0}".', url);
|
||||
@@ -42,8 +58,8 @@ function parseAppUrl(url, locationObj) {
|
||||
url = '/' + url;
|
||||
}
|
||||
var match = urlResolve(url);
|
||||
locationObj.$$path = decodeURIComponent(prefixed && match.pathname.charAt(0) === '/' ?
|
||||
match.pathname.substring(1) : match.pathname);
|
||||
var path = prefixed && match.pathname.charAt(0) === '/' ? match.pathname.substring(1) : match.pathname;
|
||||
locationObj.$$path = decodePath(path, html5Mode);
|
||||
locationObj.$$search = parseKeyValue(match.search);
|
||||
locationObj.$$hash = decodeURIComponent(match.hash);
|
||||
|
||||
@@ -118,7 +134,7 @@ function LocationHtml5Url(appBase, appBaseNoFile, basePrefix) {
|
||||
appBaseNoFile);
|
||||
}
|
||||
|
||||
parseAppUrl(pathUrl, this);
|
||||
parseAppUrl(pathUrl, this, true);
|
||||
|
||||
if (!this.$$path) {
|
||||
this.$$path = '/';
|
||||
@@ -221,7 +237,7 @@ function LocationHashbangUrl(appBase, appBaseNoFile, hashPrefix) {
|
||||
}
|
||||
}
|
||||
|
||||
parseAppUrl(withoutHashUrl, this);
|
||||
parseAppUrl(withoutHashUrl, this, false);
|
||||
|
||||
this.$$path = removeWindowsDriveName(this.$$path, withoutHashUrl, appBase);
|
||||
|
||||
@@ -406,7 +422,7 @@ var locationPrototype = {
|
||||
}
|
||||
|
||||
var match = PATH_MATCH.exec(url);
|
||||
if (match[1] || url === '') this.path(decodeURIComponent(match[1]));
|
||||
if (match[1] || url === '') this.path(decodeURI(match[1]));
|
||||
if (match[2] || match[1] || url === '') this.search(match[3] || '');
|
||||
this.hash(match[5] || '');
|
||||
|
||||
|
||||
@@ -477,6 +477,17 @@ describe('$location', function() {
|
||||
expect(locationUrl.hash()).toBe('x <>#');
|
||||
});
|
||||
|
||||
|
||||
it('should not decode encoded forward slashes in the path', function() {
|
||||
var locationUrl = new LocationHtml5Url('http://host.com/base/', 'http://host.com/base/');
|
||||
locationUrl.$$parse('http://host.com/base/a/ng2;path=%2Fsome%2Fpath');
|
||||
expect(locationUrl.path()).toBe('/a/ng2;path=%2Fsome%2Fpath');
|
||||
expect(locationUrl.search()).toEqual({});
|
||||
expect(locationUrl.hash()).toBe('');
|
||||
expect(locationUrl.url()).toBe('/a/ng2;path=%2Fsome%2Fpath');
|
||||
expect(locationUrl.absUrl()).toBe('http://host.com/base/a/ng2;path=%2Fsome%2Fpath');
|
||||
});
|
||||
|
||||
it('should decode pluses as spaces in urls', function() {
|
||||
var locationUrl = new LocationHtml5Url('http://host.com/', 'http://host.com/');
|
||||
locationUrl.$$parse('http://host.com/?a+b=c+d');
|
||||
|
||||
Reference in New Issue
Block a user