Fix bug parsing url query with escaped & or = (#4172)
I have tested this manually: <img width="727" alt="Screenshot 2024-03-14 at 19 38 34" src="https://github.com/emilk/egui/assets/1148717/fa1f6da4-d9e3-4f08-9812-1d61479dfd52">
This commit is contained in:
parent
c5eaba43cd
commit
bf7ffb982a
|
|
@ -718,7 +718,7 @@ pub struct WebInfo {
|
|||
#[cfg(target_arch = "wasm32")]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Location {
|
||||
/// The full URL (`location.href`) without the hash.
|
||||
/// The full URL (`location.href`) without the hash, percent-decoded.
|
||||
///
|
||||
/// Example: `"http://www.example.com:80/index.html?foo=bar"`.
|
||||
pub url: String,
|
||||
|
|
|
|||
|
|
@ -99,28 +99,25 @@ pub fn web_location() -> epi::Location {
|
|||
.search()
|
||||
.unwrap_or_default()
|
||||
.strip_prefix('?')
|
||||
.map(percent_decode)
|
||||
.unwrap_or_default();
|
||||
|
||||
let query_map = parse_query_map(&query)
|
||||
.iter()
|
||||
.map(|(k, v)| ((*k).to_owned(), (*v).to_owned()))
|
||||
.collect();
|
||||
.unwrap_or_default()
|
||||
.to_owned();
|
||||
|
||||
epi::Location {
|
||||
// TODO(emilk): should we really percent-decode the url? 🤷♂️
|
||||
url: percent_decode(&location.href().unwrap_or_default()),
|
||||
protocol: percent_decode(&location.protocol().unwrap_or_default()),
|
||||
host: percent_decode(&location.host().unwrap_or_default()),
|
||||
hostname: percent_decode(&location.hostname().unwrap_or_default()),
|
||||
port: percent_decode(&location.port().unwrap_or_default()),
|
||||
hash,
|
||||
query_map: parse_query_map(&query),
|
||||
query,
|
||||
query_map,
|
||||
origin: percent_decode(&location.origin().unwrap_or_default()),
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_query_map(query: &str) -> BTreeMap<&str, &str> {
|
||||
/// query is percent-encoded
|
||||
fn parse_query_map(query: &str) -> BTreeMap<String, String> {
|
||||
query
|
||||
.split('&')
|
||||
.filter_map(|pair| {
|
||||
|
|
@ -128,15 +125,16 @@ fn parse_query_map(query: &str) -> BTreeMap<&str, &str> {
|
|||
None
|
||||
} else {
|
||||
Some(if let Some((key, value)) = pair.split_once('=') {
|
||||
(key, value)
|
||||
(percent_decode(key), percent_decode(value))
|
||||
} else {
|
||||
(pair, "")
|
||||
(percent_decode(pair), String::new())
|
||||
})
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
// TODO(emilk): this test is never acgtually run, because this whole module is wasm32 only 🤦♂️
|
||||
#[test]
|
||||
fn test_parse_query() {
|
||||
assert_eq!(parse_query_map(""), BTreeMap::default());
|
||||
|
|
@ -157,4 +155,11 @@ fn test_parse_query() {
|
|||
parse_query_map("foo&baz&&"),
|
||||
BTreeMap::from_iter([("foo", ""), ("baz", "")])
|
||||
);
|
||||
assert_eq!(
|
||||
parse_query_map("badger=data.rrd%3Fparam1%3Dfoo%26param2%3Dbar&mushroom=snake"),
|
||||
BTreeMap::from_iter([
|
||||
("badger", "data.rrd?param1=foo¶m2=bar"),
|
||||
("mushroom", "snake")
|
||||
])
|
||||
);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue