aether/sandbox/
context.rs

1//! 沙箱上下文(线程局部存储)
2//!
3//! 使用线程局部存储来传递 PathValidator 给内置函数,避免修改函数签名。
4
5use super::PathValidator;
6use std::cell::RefCell;
7
8// 线程局部的沙箱上下文
9thread_local! {
10    static FILESYSTEM_VALIDATOR: RefCell<Option<PathValidator>> = const { RefCell::new(None) };
11}
12
13/// 设置文件系统路径验证器(线程局部)
14pub fn set_filesystem_validator(validator: Option<PathValidator>) {
15    FILESYSTEM_VALIDATOR.with(|v| *v.borrow_mut() = validator);
16}
17
18/// 获取文件系统路径验证器(线程局部)
19pub fn get_filesystem_validator() -> Option<PathValidator> {
20    FILESYSTEM_VALIDATOR.with(|v| v.borrow().clone())
21}
22
23/// 在作用域内设置验证器(RAII 模式)
24pub struct ScopedValidator {
25    _private: (),
26}
27
28impl ScopedValidator {
29    /// 设置验证器并在作用域结束时自动恢复
30    pub fn set(validator: PathValidator) -> Self {
31        set_filesystem_validator(Some(validator));
32        Self { _private: () }
33    }
34}
35
36impl Drop for ScopedValidator {
37    fn drop(&mut self) {
38        set_filesystem_validator(None);
39    }
40}
41
42#[cfg(test)]
43mod tests {
44    use super::*;
45
46    #[test]
47    fn test_validator_context() {
48        let validator = PathValidator::with_root_dir(std::path::PathBuf::from("/safe"));
49
50        // 设置验证器
51        set_filesystem_validator(Some(validator.clone()));
52
53        // 获取验证器
54        let retrieved = get_filesystem_validator().unwrap();
55        assert_eq!(
56            retrieved.restriction().root_dir,
57            validator.restriction().root_dir
58        );
59
60        // 清除验证器
61        set_filesystem_validator(None);
62        assert!(get_filesystem_validator().is_none());
63    }
64
65    #[test]
66    fn test_scoped_validator() {
67        assert!(get_filesystem_validator().is_none());
68
69        {
70            let validator = PathValidator::with_root_dir(std::path::PathBuf::from("/safe"));
71            let _scope = ScopedValidator::set(validator);
72
73            // 在作用域内验证器存在
74            assert!(get_filesystem_validator().is_some());
75        }
76
77        // 作用域结束后验证器自动清除
78        assert!(get_filesystem_validator().is_none());
79    }
80}