Skip to content

Commit

Permalink
fix(Router): handling of special chars in dynamic segments
Browse files Browse the repository at this point in the history
Closes #7804
  • Loading branch information
vicb committed Mar 29, 2016
1 parent 1c20a62 commit 0bcfcde
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 2 deletions.
44 changes: 42 additions & 2 deletions modules/angular2/src/router/rules/route_paths/param_route_path.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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)));
}
}

Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
}
Original file line number Diff line number Diff line change
Expand Up @@ -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');
Expand Down

0 comments on commit 0bcfcde

Please sign in to comment.