Skip to content

Commit 316fa4b

Browse files
authored
Return BadRequest for non-unicode static paths and add test (#1252)
* Fix non-unicode DB filesystem regression test * Fix non-unicode DB fs routing test
1 parent db91902 commit 316fa4b

File tree

2 files changed

+54
-6
lines changed

2 files changed

+54
-6
lines changed

src/webserver/http.rs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -500,12 +500,11 @@ pub async fn main_handler(
500500
Serve(path) => {
501501
let if_modified_since = IfModifiedSince::parse(&service_request).ok();
502502
let app_state: &web::Data<AppState> = service_request.app_data().expect("app_state");
503-
serve_file(
504-
path.as_os_str().to_str().unwrap(),
505-
app_state,
506-
if_modified_since,
507-
)
508-
.await
503+
let path = path
504+
.as_os_str()
505+
.to_str()
506+
.ok_or_else(|| ErrorBadRequest("requested file path must be valid unicode"))?;
507+
serve_file(path, app_state, if_modified_since).await
509508
}
510509
}
511510
.map(|response| service_request.into_response(response))

tests/core/mod.rs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,55 @@ async fn test_routing_with_db_fs() {
8787
);
8888
}
8989

90+
#[cfg(unix)]
91+
#[actix_web::test]
92+
async fn test_non_unicode_static_path_returns_bad_request_with_db_fs() {
93+
let mut config = test_config();
94+
if !config.database_url.starts_with("sqlite") {
95+
return;
96+
}
97+
config.database_url =
98+
"sqlite://file:test_non_unicode_static_path?mode=memory&cache=shared".to_string();
99+
100+
let state = AppState::init(&config).await.unwrap();
101+
let expected_db_path = "\u{FFFD}.txt";
102+
let mut conn = state.db.connection.acquire().await.unwrap();
103+
104+
(&mut *conn)
105+
.execute(sqlpage::filesystem::DbFsQueries::get_create_table_sql(
106+
sqlpage::webserver::database::SupportedDatabase::Sqlite,
107+
))
108+
.await
109+
.unwrap();
110+
let insert_sql = format!(
111+
"INSERT INTO sqlpage_files(path, contents) VALUES ({}, {})",
112+
make_placeholder(state.db.info.kind, 1),
113+
make_placeholder(state.db.info.kind, 2)
114+
);
115+
sqlx::query(&insert_sql)
116+
.bind(expected_db_path)
117+
.bind("file from db fs".as_bytes())
118+
.execute(&mut *conn)
119+
.await
120+
.unwrap();
121+
drop(conn);
122+
123+
let state = AppState::init(&config).await.unwrap();
124+
let app_data = actix_web::web::Data::new(state);
125+
let req = test::TestRequest::get()
126+
.uri("/%FF.txt")
127+
.app_data(app_data)
128+
.to_srv_request();
129+
130+
let err = sqlpage::webserver::http::main_handler(req)
131+
.await
132+
.expect_err("non-unicode path should not panic and must return bad request");
133+
assert_eq!(
134+
err.as_response_error().status_code(),
135+
StatusCode::BAD_REQUEST
136+
);
137+
}
138+
90139
#[actix_web::test]
91140
async fn test_routing_with_prefix() {
92141
let mut config = test_config();

0 commit comments

Comments
 (0)