From 58c4d05e4e680f770f066fdfaf880c1cf2880067 Mon Sep 17 00:00:00 2001 From: ppom <> Date: Tue, 29 Apr 2025 12:00:00 +0200 Subject: [PATCH 1/2] Remove url-encoded surrounding quotes to URL parameters Fix #879 --- .../sqlpage_functions/url_parameter_deserializer.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/webserver/database/sqlpage_functions/url_parameter_deserializer.rs b/src/webserver/database/sqlpage_functions/url_parameter_deserializer.rs index 54caa557..be371fb0 100644 --- a/src/webserver/database/sqlpage_functions/url_parameter_deserializer.rs +++ b/src/webserver/database/sqlpage_functions/url_parameter_deserializer.rs @@ -59,7 +59,14 @@ impl<'de> Deserialize<'de> for URLParameters { out.encode_and_push(&key); out.0.push_str("[]"); out.0.push('='); - out.encode_and_push(&val.to_string()); + + let val = val.to_string(); + // Remove any surrounding quotes added by serde_json + out.encode_and_push(if val.starts_with("\"") && val.ends_with("\"") { + &val[1..val.len() - 1] + } else { + &val + }); } } else { out.push_kv(&key, value); From fcc1c550454f883cc03d7e9c63741e12992dec2d Mon Sep 17 00:00:00 2001 From: lovasoa Date: Tue, 20 May 2025 01:05:24 +0200 Subject: [PATCH 2/2] fix special character handling --- .../url_parameter_deserializer.rs | 40 +++++++++++++++---- 1 file changed, 33 insertions(+), 7 deletions(-) diff --git a/src/webserver/database/sqlpage_functions/url_parameter_deserializer.rs b/src/webserver/database/sqlpage_functions/url_parameter_deserializer.rs index be371fb0..b910cd36 100644 --- a/src/webserver/database/sqlpage_functions/url_parameter_deserializer.rs +++ b/src/webserver/database/sqlpage_functions/url_parameter_deserializer.rs @@ -1,5 +1,6 @@ use percent_encoding::{percent_encode, NON_ALPHANUMERIC}; use serde::{Deserialize, Deserializer}; +use serde_json::Value; use std::borrow::Cow; use std::fmt; @@ -60,13 +61,11 @@ impl<'de> Deserialize<'de> for URLParameters { out.0.push_str("[]"); out.0.push('='); - let val = val.to_string(); - // Remove any surrounding quotes added by serde_json - out.encode_and_push(if val.starts_with("\"") && val.ends_with("\"") { - &val[1..val.len() - 1] - } else { - &val - }); + let val = match val { + Value::String(s) => s, + other => other.to_string(), + }; + out.encode_and_push(&val); } } else { out.push_kv(&key, value); @@ -96,3 +95,30 @@ fn test_url_parameters_deserializer() { "x=hello%20world&num=123&arr[]=1&arr[]=2&arr[]=3" ); } + +#[test] +fn test_url_parameters_deserializer_special_chars() { + use serde_json::json; + let json = json!({ + "chars": ["\n", " ", "\""], + }); + + let url_parameters: URLParameters = serde_json::from_value(json).unwrap(); + assert_eq!(url_parameters.0, "chars[]=%0A&chars[]=%20&chars[]=%22"); +} + +#[test] +fn test_url_parameters_deserializer_issue_879() { + use serde_json::json; + let json = json!({ + "name": "John Doe & Son's", + "items": [1, "item 2 & 3", true], + "special_char": "%&=+ ", + }); + + let url_parameters: URLParameters = serde_json::from_value(json).unwrap(); + assert_eq!( + url_parameters.0, + "name=John%20Doe%20%26%20Son%27s&items[]=1&items[]=item%202%20%26%203&items[]=true&special%5Fchar=%25%26%3D%2B%20" + ); +}