diff --git a/src/url/urlMatcher.ts b/src/url/urlMatcher.ts index 218994cc..599cccbd 100644 --- a/src/url/urlMatcher.ts +++ b/src/url/urlMatcher.ts @@ -341,8 +341,12 @@ export class UrlMatcher { private _getDecodedParamValue(value: any, param: Param): any { if (isDefined(value)) { - if (this.config.decodeParams && !param.type.raw && !isArray(value)) { - value = decodeURIComponent(value); + if (this.config.decodeParams && !param.type.raw) { + if (isArray(value)) { + value = value.map((paramValue) => decodeURIComponent(paramValue)); + } else { + value = decodeURIComponent(value); + } } value = param.type.decode(value); diff --git a/test/urlMatcherFactorySpec.ts b/test/urlMatcherFactorySpec.ts index 96f60ede..a4a794ca 100644 --- a/test/urlMatcherFactorySpec.ts +++ b/test/urlMatcherFactorySpec.ts @@ -449,6 +449,12 @@ describe('UrlMatcher', function () { expect(m.exec($location.path(), $location.search())).toEqual({ param1: 'bar,baz' }); // coerced to string expect(m.format({ param1: ['bar', 'baz'] })).toBe('/foo?param1=bar%2Cbaz'); // coerced to string }); + + it('should decode query parameter values', function () { + const m = $umf.compile('/foo?param1', { state: {} }); + $location.url('/foo?param1=%25¶m1=%2F'); + expect(m.exec($location.path(), $location.search())).toEqual({ param1: ['%', '/'] }); + }); }); describe('multivalue-path-parameters', function () {