#![cfg(unix)]
use crate::soft_canonicalize;
use std::{fs, thread, time::Duration};
use tempfile::Builder;
#[test]
fn test_cve_2022_21658_race_condition() {
let temp_dir = Builder::new().prefix("cve_test").tempdir().unwrap();
let root = temp_dir.path();
let real_target = root.join("real_target");
fs::create_dir(&real_target).unwrap();
let symlink_path = root.join("symlink");
std::os::unix::fs::symlink(&real_target, &symlink_path).unwrap();
let secret_target = root.join("secret_target");
fs::create_dir(&secret_target).unwrap();
let symlink_path_clone = symlink_path.clone();
let handle = thread::spawn(move || {
thread::sleep(Duration::from_millis(10));
fs::remove_file(&symlink_path_clone).unwrap();
std::os::unix::fs::symlink(&secret_target, &symlink_path_clone).unwrap();
});
let result = soft_canonicalize(&symlink_path);
handle.join().unwrap();
let expected = std::fs::canonicalize(&real_target).unwrap_or(real_target);
assert_eq!(result.unwrap(), expected);
}