@@ -4,6 +4,10 @@ use sqlpage::{
44 AppState ,
55} ;
66use sqlx:: Executor as _;
7+ #[ cfg( unix) ]
8+ use std:: ffi:: OsString ;
9+ #[ cfg( unix) ]
10+ use std:: os:: unix:: ffi:: OsStringExt ;
711
812use crate :: common:: { make_app_data_from_config, req_path, req_path_with_app_data, test_config} ;
913
@@ -87,6 +91,65 @@ async fn test_routing_with_db_fs() {
8791 ) ;
8892}
8993
94+ #[ actix_web:: test]
95+ async fn test_non_unicode_static_path_returns_bad_request_with_db_fs ( ) {
96+ let mut config = test_config ( ) ;
97+ if !config. database_url . starts_with ( "sqlite" ) {
98+ return ;
99+ }
100+ config. database_url =
101+ "sqlite://file:test_non_unicode_static_path?mode=memory&cache=shared" . to_string ( ) ;
102+
103+ let expected_db_path = {
104+ let decoded = percent_encoding:: percent_decode_str ( "%FF.txt" ) ;
105+ #[ cfg( unix) ]
106+ {
107+ std:: path:: PathBuf :: from ( OsString :: from_vec ( decoded. collect :: < Vec < u8 > > ( ) ) )
108+ . display ( )
109+ . to_string ( )
110+ }
111+ #[ cfg( not( unix) ) ]
112+ {
113+ decoded. decode_utf8_lossy ( ) . to_string ( )
114+ }
115+ } ;
116+
117+ use sqlx:: Connection as _;
118+ let mut conn = sqlx:: AnyConnection :: connect ( & config. database_url )
119+ . await
120+ . unwrap ( ) ;
121+ conn. execute ( "DROP TABLE IF EXISTS sqlpage_files" )
122+ . await
123+ . unwrap ( ) ;
124+ conn. execute ( sqlpage:: filesystem:: DbFsQueries :: get_create_table_sql (
125+ sqlpage:: webserver:: database:: SupportedDatabase :: Sqlite ,
126+ ) )
127+ . await
128+ . unwrap ( ) ;
129+ sqlx:: query ( "INSERT INTO sqlpage_files(path, contents) VALUES (?, ?)" )
130+ . bind ( expected_db_path)
131+ . bind ( "file from db fs" . as_bytes ( ) )
132+ . execute ( & mut conn)
133+ . await
134+ . unwrap ( ) ;
135+
136+ let state = AppState :: init ( & config) . await . unwrap ( ) ;
137+
138+ let app_data = actix_web:: web:: Data :: new ( state) ;
139+ let req = test:: TestRequest :: get ( )
140+ . uri ( "/%FF.txt" )
141+ . app_data ( app_data)
142+ . to_srv_request ( ) ;
143+
144+ let err = sqlpage:: webserver:: http:: main_handler ( req)
145+ . await
146+ . expect_err ( "non-unicode path should not panic and must return bad request" ) ;
147+ assert_eq ! (
148+ err. as_response_error( ) . status_code( ) ,
149+ StatusCode :: BAD_REQUEST
150+ ) ;
151+ }
152+
90153#[ actix_web:: test]
91154async fn test_routing_with_prefix ( ) {
92155 let mut config = test_config ( ) ;
0 commit comments