Description
Problem
When reading a path parameter from a route, yew-router does not decode escaped characters in the path segment, and passes them to the user as they are in the URL string.
When navigating via Link
, path parameters are not encoded, leading to issues when path components have spaces, forward slashes, and other forbidden characters in them.
Steps To Reproduce
Example application:
use yew::prelude::*;
use yew_router::prelude::*;
#[derive(Clone, Routable, PartialEq)]
enum Route {
#[at("/")]
Root,
#[at("/search/:query")]
Search { query: String },
}
fn switch(route: Route) -> Html {
match route {
Route::Root => html!{
<Link<Route> to={Route::Search { query: "foo bar baz".into() }}>
{"Do search!"}
</Link<Route>>
},
Route::Search { query } => html!{
<p>{"You searched for: "}<code>{query.clone()}</code></p>
},
}
}
#[function_component]
fn App() -> Html {
html!{
<BrowserRouter>
<Switch<Route> render={switch} />
</BrowserRouter>
}
}
fn main() {
yew::Renderer::<App>::new().render();
}
Clicking the link navigates to Route::Search { query: "foo bar baz" }
, whose handler just prints out the query
. Clicking the URL goes to http://127.0.0.1:8080/search/foo bar baz
which prints You searched for: foo%20bar%20baz
.
Replacing the query with "foo/bar/baz"
causes the link to go to http://127.0.0.1:8080/search/foo/bar/baz
, which is an entirely different route.
Expected behavior
When creating a URL, yew-router should percent-encode characters forbidden in URL components. When parsing a route, yew-router should decode those percent-encoded characters before parsing.
Otherwise, it's quite unintuitive and inconvenient that Routes are not "round-trip safe", and that linking to one route may lead to a different route if the path parameters contain slashes. This may also introduce a url injection vulnerability.
Environment:
- Yew version: 0.20.0 (yew-router version 0.17.0)
- Rust version: 1.66.1
- Target, if relevant: wasm32-unknown-unknown
- Build tool, if relevant: trunk
- OS, if relevant: Not relevant
- Browser and version, if relevant: Not relevant
Questionnaire
- I'm interested in fixing this myself but don't know where to start
- I would like to fix and I have a solution
- I don't have time to fix this right now, but maybe later