fix(Router): handling of special chars in dynamic segments
Closes #7804
This commit is contained in:
parent
1c20a62611
commit
0bcfcde63d
|
@ -62,7 +62,7 @@ class DynamicPathSegment implements PathSegment {
|
||||||
throw new BaseException(
|
throw new BaseException(
|
||||||
`Route generator for '${this.name}' was not included in parameters passed.`);
|
`Route generator for '${this.name}' was not included in parameters passed.`);
|
||||||
}
|
}
|
||||||
return normalizeString(params.get(this.name));
|
return encodeDynamicSegment(normalizeString(params.get(this.name)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,7 +130,7 @@ export class ParamRoutePath implements RoutePath {
|
||||||
captured.push(currentUrlSegment.path);
|
captured.push(currentUrlSegment.path);
|
||||||
|
|
||||||
if (pathSegment instanceof DynamicPathSegment) {
|
if (pathSegment instanceof DynamicPathSegment) {
|
||||||
positionalParams[pathSegment.name] = currentUrlSegment.path;
|
positionalParams[pathSegment.name] = decodeDynamicSegment(currentUrlSegment.path);
|
||||||
} else if (!pathSegment.match(currentUrlSegment.path)) {
|
} else if (!pathSegment.match(currentUrlSegment.path)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -269,3 +269,43 @@ export class ParamRoutePath implements RoutePath {
|
||||||
}
|
}
|
||||||
static RESERVED_CHARS = RegExpWrapper.create('//|\\(|\\)|;|\\?|=');
|
static RESERVED_CHARS = RegExpWrapper.create('//|\\(|\\)|;|\\?|=');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let REGEXP_PERCENT = /%/g;
|
||||||
|
let REGEXP_SLASH = /\//g;
|
||||||
|
let REGEXP_OPEN_PARENT = /\(/g;
|
||||||
|
let REGEXP_CLOSE_PARENT = /\)/g;
|
||||||
|
let REGEXP_SEMICOLON = /;/g;
|
||||||
|
|
||||||
|
function encodeDynamicSegment(value: string): string {
|
||||||
|
if (isBlank(value)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
value = StringWrapper.replaceAll(value, REGEXP_PERCENT, '%25');
|
||||||
|
value = StringWrapper.replaceAll(value, REGEXP_SLASH, '%2F');
|
||||||
|
value = StringWrapper.replaceAll(value, REGEXP_OPEN_PARENT, '%28');
|
||||||
|
value = StringWrapper.replaceAll(value, REGEXP_CLOSE_PARENT, '%29');
|
||||||
|
value = StringWrapper.replaceAll(value, REGEXP_SEMICOLON, '%3B');
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
let REGEXP_ENC_SEMICOLON = /%3B/ig;
|
||||||
|
let REGEXP_ENC_CLOSE_PARENT = /%29/ig;
|
||||||
|
let REGEXP_ENC_OPEN_PARENT = /%28/ig;
|
||||||
|
let REGEXP_ENC_SLASH = /%2F/ig;
|
||||||
|
let REGEXP_ENC_PERCENT = /%25/ig;
|
||||||
|
|
||||||
|
function decodeDynamicSegment(value: string): string {
|
||||||
|
if (isBlank(value)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
value = StringWrapper.replaceAll(value, REGEXP_ENC_SEMICOLON, ';');
|
||||||
|
value = StringWrapper.replaceAll(value, REGEXP_ENC_CLOSE_PARENT, ')');
|
||||||
|
value = StringWrapper.replaceAll(value, REGEXP_ENC_OPEN_PARENT, '(');
|
||||||
|
value = StringWrapper.replaceAll(value, REGEXP_ENC_SLASH, '/');
|
||||||
|
value = StringWrapper.replaceAll(value, REGEXP_ENC_PERCENT, '%');
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
|
@ -50,6 +50,33 @@ export function main() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('dynamic segments', () => {
|
||||||
|
it('should parse parameters', () => {
|
||||||
|
var rec = new ParamRoutePath('/test/:id');
|
||||||
|
var url = new Url('test', new Url('abc'));
|
||||||
|
var match = rec.matchUrl(url);
|
||||||
|
expect(match.allParams).toEqual({'id': 'abc'});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should decode special characters when parsing', () => {
|
||||||
|
var rec = new ParamRoutePath('/test/:id');
|
||||||
|
var url = new Url('test', new Url('abc%25%2F%2f%28%29%3B'));
|
||||||
|
var match = rec.matchUrl(url);
|
||||||
|
expect(match.allParams).toEqual({'id': 'abc%//();'});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should generate url', () => {
|
||||||
|
var rec = new ParamRoutePath('/test/:id');
|
||||||
|
expect(rec.generateUrl({'id': 'abc'}).urlPath).toEqual('test/abc');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should encode special characters when generating', () => {
|
||||||
|
var rec = new ParamRoutePath('/test/:id');
|
||||||
|
expect(rec.generateUrl({'id': 'abc/def/%();'}).urlPath)
|
||||||
|
.toEqual('test/abc%2Fdef%2F%25%28%29%3B');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('matrix params', () => {
|
describe('matrix params', () => {
|
||||||
it('should be parsed along with dynamic paths', () => {
|
it('should be parsed along with dynamic paths', () => {
|
||||||
var rec = new ParamRoutePath('/hello/:id');
|
var rec = new ParamRoutePath('/hello/:id');
|
||||||
|
|
Loading…
Reference in New Issue