Skip to content
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

[Bug]: generateRoute() removing the last asterisk if it's part of the param string #9051

Closed
trainoasis opened this issue Jul 12, 2022 · 7 comments

Comments

@trainoasis
Copy link

What version of React Router are you using?

6.3.0

Steps to Reproduce

const path = generatePath("/route/:name", {
    name: "includes *asterisk at the end*",
})

Expected Behavior

I would expect for the above to return /route/includes *asterisk at the end*

Actual Behavior

It returns /route/includes *asterisk at the end

@trainoasis trainoasis added the bug label Jul 12, 2022
@timdorr
Copy link
Member

timdorr commented Jul 12, 2022

I'm not 100% sure this is a valid bug. Yes, it's not doing what you're expecting, but that's also not a valid path, as * and spaces aren't valid characters (they should be URL encoded).

@trainoasis
Copy link
Author

trainoasis commented Jul 25, 2022

@timdorr thanks for your reply. Actually we used encodeURIComponent but this does not URL encode * by design.

Should we force URL encode this as a "unique" condition in our code as %2A? That also does not seem very nice to be honest, so I'm a little confused. What do you think?

@timdorr
Copy link
Member

timdorr commented Jul 25, 2022

Sorry, I shouldn't have said asterisks are encoded. They are not according to the spec (section 2.2).

You can also use + for spaces in URLs. But what you're passing into generateRoute should use valid URL characters otherwise. Encoding them is a good first step.

@trainoasis
Copy link
Author

We are in fact encoding, I just didn't show that in my initial post, we do use encodeURIComponent like so:

const path = generatePath("/route/:name", {
    name: encodeURIComponent("includes *asterisk at the end*"),
})

Unfortunately the asterisk at the end for some reason gets stripped, so there's only "ugly" solutions such as

  1. manually add * it if it's at the end on the first place (after generatePath)
  2. use something like str.replaceAll("*", "%2A"); before passing to generatePath

I guess it's only me running into this, so it seems will have to take one of the dirty approaches for now.
If there's any other approaches or actual solutions I can take, I'd be happy to hear them. Thanks!

Obi-Dann added a commit to Obi-Dann/react-router that referenced this issue Feb 9, 2023
generatePath was doing multiple passes on the `path` using string replace, the first two passes were applying parameters, the third pass was doing a cleanup and the fourth path was applying the `splat`.
It was possible to get incorrect results while applying `splat` when the last parameter value ended with `*`:

```ts
const path = generatePath("/route/:name", {
    name: encodeURIComponent("includes *asterisk at the end*"),
})
```
```
    Expected: "/route/includes *asterisk at the end*"
    Received: "/route/includes *asterisk at the end"
```
results of the first two passes return the value of `/route/*asterisk at the end*` which was later treated as path with the splat resulting in the last asterisk removed.

it was also possible to inject the splat value unintentionally
```ts
generatePath("/courses/:name", { name: "foo*", "*": "splat_should_not_be_added" })
```
```
    Expected: "/courses/foo*"
    Received: "/courses/foosplat_should_not_be_added"
```

A safer option, instead of mutating a global path multiple times, is to split the path into segments, process each segment in isolation and then join them back together.

fixes remix-run#9051
@Obi-Dann
Copy link
Contributor

Obi-Dann commented Feb 9, 2023

@trainoasis FYI, I've got a PR fixing the issue. generatePath will use safer parameter interpolation once it's merged. #10078

@github-actions
Copy link
Contributor

This issue has been automatically marked stale because we haven't received a response from the original author in a while 🙈. This automation helps keep the issue tracker clean from issues that are not actionable. Please reach out if you have more information for us or you think this issue shouldn't be closed! 🙂 If you don't do so within 7 days, this issue will be automatically closed.

@brophdawg11
Copy link
Contributor

This was released in 6.9.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants