From 40c702ee4ecbfc6fdf67776759d57cd6d3a13c18 Mon Sep 17 00:00:00 2001 From: lovasoa Date: Mon, 3 Feb 2025 02:27:05 +0100 Subject: [PATCH] fix handling of special characters in file names --- src/webserver/routing.rs | 16 +++++++++++++++- tests/index.rs | 11 +++++++++++ tests/spaces in file name.sql | 1 + 3 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 tests/spaces in file name.sql diff --git a/src/webserver/routing.rs b/src/webserver/routing.rs index 156525b3..3c5e9fa0 100644 --- a/src/webserver/routing.rs +++ b/src/webserver/routing.rs @@ -3,6 +3,8 @@ use crate::webserver::database::ParsedSqlFile; use crate::{file_cache::FileCache, AppState}; use awc::http::uri::PathAndQuery; use log::debug; +use percent_encoding; +use std::ffi::OsString; use std::path::{Path, PathBuf}; use RoutingAction::{CustomNotFound, Execute, NotFound, Redirect, Serve}; @@ -88,7 +90,19 @@ where { match path_and_query.path().strip_prefix(config.prefix()) { None => Err(Redirect(config.prefix().to_string())), - Some(path) => Ok(PathBuf::from(path)), + Some(path) => { + let decoded = percent_encoding::percent_decode_str(path); + #[cfg(unix)] + { + use std::os::unix::ffi::OsStringExt; + let decoded = decoded.collect::>(); + Ok(PathBuf::from(OsString::from_vec(decoded))) + } + #[cfg(not(unix))] + { + Ok(PathBuf::from(decoded.decode_utf8_lossy().as_ref())) + } + } } } diff --git a/tests/index.rs b/tests/index.rs index 1baa7670..e5377376 100644 --- a/tests/index.rs +++ b/tests/index.rs @@ -569,6 +569,17 @@ async fn test_static_files() { assert_eq!(&body, &b"It works !"[..]); } +#[actix_web::test] +async fn test_spaces_in_file_names() { + let resp = req_path("/tests/spaces%20in%20file%20name.sql") + .await + .unwrap(); + assert_eq!(resp.status(), http::StatusCode::OK); + let body = test::read_body(resp).await; + let body_str = String::from_utf8(body.to_vec()).unwrap(); + assert!(body_str.contains("It works !"), "{body_str}"); +} + #[actix_web::test] async fn test_with_site_prefix() { let mut config = test_config(); diff --git a/tests/spaces in file name.sql b/tests/spaces in file name.sql new file mode 100644 index 00000000..d7bc7501 --- /dev/null +++ b/tests/spaces in file name.sql @@ -0,0 +1 @@ +select 'text' as component, 'It works !' AS contents; \ No newline at end of file