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(
|
||||
`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);
|
||||
|
||||
if (pathSegment instanceof DynamicPathSegment) {
|
||||
positionalParams[pathSegment.name] = currentUrlSegment.path;
|
||||
positionalParams[pathSegment.name] = decodeDynamicSegment(currentUrlSegment.path);
|
||||
} else if (!pathSegment.match(currentUrlSegment.path)) {
|
||||
return null;
|
||||
}
|
||||
|
@ -269,3 +269,43 @@ export class ParamRoutePath implements RoutePath {
|
|||
}
|
||||
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', () => {
|
||||
it('should be parsed along with dynamic paths', () => {
|
||||
var rec = new ParamRoutePath('/hello/:id');
|
||||
|
|
Loading…
Reference in New Issue