use super::*; #[test] fn quoted_filename_preserves_semicolons_and_escaped_quotes() { let directory = Directory::new(); let bytes = String::from_utf8(content(b"data")) .unwrap() .replace("filename=image.bin", r#"filename="semi;with\"quote.bin""#) .into_bytes(); Runtime::new(TaskLimits::default()) .unwrap() .run(async |scope| { let mut parsed = upload::decode( body(&bytes, 1), "multipart/form-data; boundary=\"boundary\"", &directory.0, &Limits::default(), scope, ) .await .unwrap(); let file = parsed.take("file").unwrap(); assert_eq!(file.filename(), "semi;with\"quote.bin"); file.close(); assert_eq!(directory.temporary_count(), 0); }) .unwrap(); } #[cfg(unix)] #[test] fn parent_symlinks_cannot_redirect_temporary_or_stored_uploads() { let directory = Directory::new(); let outside = Directory::new(); let bytes = content(b"data"); std::os::unix::fs::symlink(&outside.0, directory.0.join("linked")).unwrap(); Runtime::new(TaskLimits::default()) .unwrap() .run(async |scope| { for path in [directory.0.join("linked"), directory.0.join("linked/data")] { assert!( upload::decode( body(&bytes, 7), "multipart/form-data; boundary=boundary", &path, &Limits::default(), scope ) .await .is_err() ); assert_eq!(std::fs::read_dir(&outside.0).unwrap().count(), 0); } let mut parsed = upload::decode( body(&bytes, 7), "multipart/form-data; boundary=boundary", &directory.0, &Limits::default(), scope, ) .await .unwrap(); std::os::unix::fs::symlink(&outside.0, directory.0.join("upload")).unwrap(); assert!( upload::put(parsed.take("file").unwrap(), scope) .await .is_err() ); assert_eq!(std::fs::read_dir(&outside.0).unwrap().count(), 0); assert_eq!(directory.temporary_count(), 0); }) .unwrap(); }