router icon indicating copy to clipboard operation
router copied to clipboard

Route parameters containing forward slashes are not correctly encoded.

Open luisvsilva opened this issue 5 years ago • 4 comments

I'm submitting a bug

  • Library Version: 1.6.3

Please tell us about your environment:

  • Operating System: Windows 10

  • Node Version: v10.13.0

  • NPM Version: 6.6.0

  • JSPM OR Webpack AND Version webpack 4.29.0

  • Browser: all

  • Language: TypeScript

Current behavior:

Route parameters containing forward slashes are not correctly encoded.

say this route is configured:

{ route: 'detail/:component', name: 'coded', moduleId: PLATFORM.moduleName('./coded/coded') }

navigating to the route by using:

this.router.navigateToRoute('details',{component:'some/thing'});

in the module after navigation:

activate(params:{component:string}){
     //params.component is set to 'some'
}

What is the expected behavior?

in the module after navigation:

activate(params:{component:string}){
     //params.component should be set to 'some/thing'
}

luisvsilva avatar Mar 20 '19 01:03 luisvsilva

internally the router is using encodeURI() which doesn't properly escape everything:

encodeURI escapes all characters except: A-Z a-z 0-9 ; , / ? : @ & = + $ - _ . ! ~ * ' ( ) # https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURI

It should probably use encodeURIComponent() which properly encodes the fragments. This is a significant change to the behaviour of the router and might affect existing applications

jordan-ware avatar Mar 20 '19 02:03 jordan-ware

I'd like to point out that this is a serious problem. Consider a use case where I want to send %/ as a route parameter:

  1. I have to escape it first by using encodeURIComponent(), because I can't put % directly into a URL and / would mess up the route parameters' contents.
  2. After escaping, I get the encoded string %25%2F as expected and pass it along to navigateToRoute().
  3. When I want to access the route parameter in the activate() method, for example, the router has already done some decoding (presumably using encodeURI()) and all I get is %%2F.
  4. ????
  5. How am I supposed to decode only the / (as %2F) and not %?

EDIT: if I do encodeURIComponent(encodeURI("%/")) in the first step, then I'll get %25%2F in the third step as expected. Messing with route parameters without clearly stating it anywhere is not okay, and neither is using double-encoding to bypass this issue.

hankur avatar Jan 17 '21 11:01 hankur

@hankur I think you can encode/decode your route parameters with base64 strings. So it may look like this:

  1. escape it first by using btoa(...)
  2. ...
  3. When I want to access the route parameter in the activate() method, for example, the router has already done some decoding (presumably using encodeURI()) and decode it using atob(...).

Can you try this?

bigopon avatar Jan 18 '21 12:01 bigopon

@bigopon I guess this would work, but it would render the URL unreadable by us humans. Simple encodeURIComponent() would only encode the special symbols, but text would still be understandable, which I'd prefer.

hankur avatar Jan 18 '21 12:01 hankur