@@ -880,6 +880,7 @@ impl FileXferTask {
880
880
) {
881
881
let task = async {
882
882
validate_subpath_for_download ( self . file . subpath ( ) ) ?;
883
+ validate_file_id_for_download ( self . file . id ( ) ) ?;
883
884
884
885
let emit_checksum_events = {
885
886
if let Some ( threshold) = state. config . checksum_events_size_threshold {
@@ -1164,9 +1165,26 @@ fn validate_subpath_for_download(subpath: &FileSubPath) -> crate::Result<()> {
1164
1165
Ok ( ( ) )
1165
1166
}
1166
1167
1168
+ /// Check file ID for illegal characters so that the temp file is not created in
1169
+ /// parent directories
1170
+ fn validate_file_id_for_download ( file_id : & FileId ) -> crate :: Result < ( ) > {
1171
+ const ALLOWED_BESIDE_ALPHANUMERIC : & [ char ] = & [ '_' , '-' , '=' ] ; // Add '=' just in case the padding is added
1172
+
1173
+ fn is_char_valid ( c : char ) -> bool {
1174
+ c. is_ascii_alphanumeric ( ) || ALLOWED_BESIDE_ALPHANUMERIC . contains ( & c)
1175
+ }
1176
+
1177
+ let valid = file_id. as_ref ( ) . chars ( ) . all ( is_char_valid) ;
1178
+ if !valid {
1179
+ return Err ( Error :: BadFileId ) ;
1180
+ }
1181
+
1182
+ Ok ( ( ) )
1183
+ }
1184
+
1167
1185
#[ cfg( test) ]
1168
1186
mod tests {
1169
- use crate :: file:: FileSubPath ;
1187
+ use crate :: { file:: FileSubPath , FileId } ;
1170
1188
1171
1189
#[ test]
1172
1190
fn validate_subpath ( ) {
@@ -1188,4 +1206,34 @@ mod tests {
1188
1206
Err ( crate :: Error :: FilenameTooLong )
1189
1207
) ) ;
1190
1208
}
1209
+
1210
+ #[ test]
1211
+ fn validate_file_id ( ) {
1212
+ let id = FileId :: from ( "x_ALOz5YRCXZSiS5V5Pd8VN_qqC6abyDyIBnjitzGe8" ) ;
1213
+ assert ! ( super :: validate_file_id_for_download( & id) . is_ok( ) ) ;
1214
+
1215
+ let id = FileId :: from ( "../../asdfasdf" ) ;
1216
+ assert ! ( matches!(
1217
+ super :: validate_file_id_for_download( & id) ,
1218
+ Err ( crate :: Error :: BadFileId )
1219
+ ) ) ;
1220
+
1221
+ let id = FileId :: from ( ".." ) ;
1222
+ assert ! ( matches!(
1223
+ super :: validate_file_id_for_download( & id) ,
1224
+ Err ( crate :: Error :: BadFileId )
1225
+ ) ) ;
1226
+
1227
+ let id = FileId :: from ( "/asdfasdf" ) ;
1228
+ assert ! ( matches!(
1229
+ super :: validate_file_id_for_download( & id) ,
1230
+ Err ( crate :: Error :: BadFileId )
1231
+ ) ) ;
1232
+
1233
+ let id = FileId :: from ( "C:\\ ABC" ) ;
1234
+ assert ! ( matches!(
1235
+ super :: validate_file_id_for_download( & id) ,
1236
+ Err ( crate :: Error :: BadFileId )
1237
+ ) ) ;
1238
+ }
1191
1239
}
0 commit comments