Skip to content

fix not decoding encoded path and search params when synchronising the state with the current url. #618

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Jul 17, 2020
2 changes: 2 additions & 0 deletions src/url/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ export interface UrlMatcherCompileConfig {
state?: StateDeclaration;
strict?: boolean;
caseInsensitive?: boolean;
// If params are pre-decoded, set to false to avoid double decoding
decodeParams?: boolean;
}

/** @deprecated use [[UrlConfig]] */
Expand Down
1 change: 1 addition & 0 deletions src/url/urlConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { isDefined, isString } from '../common';
*/
export class UrlConfig implements Disposable {
/** @internal */ paramTypes = new ParamTypes();
/** @internal */ _decodeParams = true;
/** @internal */ _isCaseInsensitive = false;
/** @internal */ _isStrictMode = true;
/** @internal */ _defaultSquashPolicy: boolean | string = false;
Expand Down
25 changes: 20 additions & 5 deletions src/url/urlMatcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ const defaultConfig: UrlMatcherCompileConfig = {
state: { params: {} },
strict: true,
caseInsensitive: true,
decodeParams: true,
};

/**
Expand Down Expand Up @@ -338,6 +339,18 @@ export class UrlMatcher {
return this.pattern;
}

private _getDecodedParamValue(value: any, param: Param): any {
if (isDefined(value)) {
if (this.config.decodeParams && !param.type.raw && !isArray(value)) {
value = decodeURIComponent(value);
}

value = param.type.decode(value);
}

return param.value(value);
}

/**
* Tests the specified url/path against this matcher.
*
Expand Down Expand Up @@ -406,17 +419,19 @@ export class UrlMatcher {
for (let j = 0; j < param.replace.length; j++) {
if (param.replace[j].from === value) value = param.replace[j].to;
}

if (value && param.array === true) value = decodePathArray(value);
if (isDefined(value)) value = param.type.decode(value);
values[param.id] = param.value(value);

values[param.id] = this._getDecodedParamValue(value, param);
}
searchParams.forEach((param) => {
searchParams.forEach((param: Param) => {
let value = search[param.id];

for (let j = 0; j < param.replace.length; j++) {
if (param.replace[j].from === value) value = param.replace[j].to;
}
if (isDefined(value)) value = param.type.decode(value);
values[param.id] = param.value(value);

values[param.id] = this._getDecodedParamValue(value, param);
});

if (hash) values['#'] = hash;
Expand Down
13 changes: 9 additions & 4 deletions src/url/urlMatcherFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,12 @@ export class ParamFactory {
export class UrlMatcherFactory {
/** Creates a new [[Param]] for a given location (DefType) */
paramFactory = new ParamFactory(this.router);
// TODO: Check if removal of this will break anything, then remove these
UrlMatcher: typeof UrlMatcher = UrlMatcher;
Param: typeof Param = Param;

// TODO: move implementations to UrlConfig (urlService.config)
constructor(/** @internal */ private router: UIRouter) {
extend(this, { UrlMatcher, Param });
}
constructor(/** @internal */ private router: UIRouter) {}

/**
* Creates a [[UrlMatcher]] for the specified pattern.
Expand All @@ -48,7 +49,11 @@ export class UrlMatcherFactory {
// backward-compatible support for config.params -> config.state.params
const params = config && !config.state && (config as any).params;
config = params ? { state: { params }, ...config } : config;
const globalConfig = { strict: urlConfig._isStrictMode, caseInsensitive: urlConfig._isCaseInsensitive };
const globalConfig: UrlMatcherCompileConfig = {
strict: urlConfig._isStrictMode,
caseInsensitive: urlConfig._isCaseInsensitive,
decodeParams: urlConfig._decodeParams,
};
return new UrlMatcher(pattern, urlConfig.paramTypes, this.paramFactory, extend(globalConfig, config));
}

Expand Down
Loading